import RT-Thread@9217865c without bsp, libcpu and components/net

This commit is contained in:
Zihao Yu 2023-05-20 16:23:33 +08:00
commit e2376a3709
1414 changed files with 390370 additions and 0 deletions

6
examples/libc/SConscript Normal file
View file

@ -0,0 +1,6 @@
from building import *
src = Glob('*.c')
group = DefineGroup('UTest', src, depend = ['RT_USING_NEWLIBC', 'RT_USING_PTHREADS'])
Return('group')

59
examples/libc/dirent.c Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <dirent.h>
int libc_dirent()
{
DIR * dirp;
long int save3 = 0;
long int cur;
int i = 0;
int result = 0;
struct dirent *dp;
dirp = opendir("/");
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
{
/* save position 3 (after fourth entry) */
if (i++ == 3)
save3 = telldir(dirp);
printf("%s\n", dp->d_name);
/* stop at 400 (just to make sure dirp->__offset and dirp->__size are
scrambled */
if (i == 400)
break;
}
printf("going back past 4-th entry...\n");
/* go back to saved entry */
seekdir(dirp, save3);
/* Check whether telldir equals to save3 now. */
cur = telldir(dirp);
if (cur != save3)
{
printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur);
result = 1;
}
/* print remaining files (3-last) */
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
printf("%s\n", dp->d_name);
closedir(dirp);
return result;
}
FINSH_FUNCTION_EXPORT(libc_dirent, dirent test for libc);

22
examples/libc/env.c Normal file
View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_env()
{
printf("PATH=%s\n", getenv("PATH"));
putenv("foo=bar");
printf("foo=%s\n", getenv("foo"));
return 0;
}
FINSH_FUNCTION_EXPORT(libc_env, get/set_env test);

45
examples/libc/ex1.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/* Creates two threads, one printing 10000 "a"s, the other printing
10000 "b"s.
Illustrates: thread creation, thread joining. */
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include "pthread.h"
static void *process(void * arg)
{
int i;
printf("Starting process %s\n", (char *)arg);
for (i = 0; i < 10000; i++)
write(1, (char *) arg, 1);
return NULL;
}
#define sucfail(r) (r != 0 ? "failed" : "succeeded")
int libc_ex1(void)
{
int pret, ret = 0;
pthread_t th_a, th_b;
void *retval;
ret += (pret = pthread_create(&th_a, NULL, process, (void *)"a"));
printf("create a %s %d\n", sucfail(pret), pret);
ret += (pret = pthread_create(&th_b, NULL, process, (void *)"b"));
printf("create b %s %d\n", sucfail(pret), pret);
ret += (pret = pthread_join(th_a, &retval));
printf("join a %s %d\n", sucfail(pret), pret);
ret += (pret = pthread_join(th_b, &retval));
printf("join b %s %d\n", sucfail(pret), pret);
return ret;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex1, example 1 for libc);

122
examples/libc/ex2.c Normal file
View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/* The classic producer-consumer example.
Illustrates mutexes and conditions.
All integers between 0 and 9999 should be printed exactly twice,
once to the right of the arrow and once to the left. */
#include <stdio.h>
#include "pthread.h"
#define BUFFER_SIZE 16
/* Circular buffer of integers. */
struct prodcons {
int buffer[BUFFER_SIZE]; /* the actual data */
pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */
int readpos, writepos; /* positions for reading and writing */
pthread_cond_t notempty; /* signaled when buffer is not empty */
pthread_cond_t notfull; /* signaled when buffer is not full */
};
/* Initialize a buffer */
static void init(struct prodcons * b)
{
pthread_mutex_init(&b->lock, NULL);
pthread_cond_init(&b->notempty, NULL);
pthread_cond_init(&b->notfull, NULL);
b->readpos = 0;
b->writepos = 0;
}
/* Store an integer in the buffer */
static void put(struct prodcons * b, int data)
{
pthread_mutex_lock(&b->lock);
/* Wait until buffer is not full */
while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {
pthread_cond_wait(&b->notfull, &b->lock);
/* pthread_cond_wait reacquired b->lock before returning */
}
/* Write the data and advance write pointer */
b->buffer[b->writepos] = data;
b->writepos++;
if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
/* Signal that the buffer is now not empty */
pthread_cond_signal(&b->notempty);
pthread_mutex_unlock(&b->lock);
}
/* Read and remove an integer from the buffer */
static int get(struct prodcons * b)
{
int data;
pthread_mutex_lock(&b->lock);
/* Wait until buffer is not empty */
while (b->writepos == b->readpos) {
pthread_cond_wait(&b->notempty, &b->lock);
}
/* Read the data and advance read pointer */
data = b->buffer[b->readpos];
b->readpos++;
if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
/* Signal that the buffer is now not full */
pthread_cond_signal(&b->notfull);
pthread_mutex_unlock(&b->lock);
return data;
}
/* A test program: one thread inserts integers from 1 to 10000,
the other reads them and prints them. */
#define OVER (-1)
struct prodcons buffer;
static void * producer(void * data)
{
int n;
for (n = 0; n < 10000; n++) {
printf("%d --->\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
return NULL;
}
static void * consumer(void * data)
{
int d;
while (1) {
d = get(&buffer);
if (d == OVER) break;
printf("---> %d\n", d);
}
return NULL;
}
int libc_ex2(void)
{
pthread_t th_a, th_b;
void * retval;
init(&buffer);
/* Create the threads */
pthread_create(&th_a, NULL, producer, 0);
pthread_create(&th_b, NULL, consumer, 0);
/* Wait until producer and consumer finish. */
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex2, example 2 for libc);

162
examples/libc/ex3.c Normal file
View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/* Multi-thread searching.
Illustrates: thread cancellation, cleanup handlers. */
#include <sys/errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
/* Defines the number of searching threads */
#define NUM_THREADS 5
/* Function prototypes */
void *search(void *);
void print_it(void *);
/* Global variables */
pthread_t threads[NUM_THREADS];
pthread_mutex_t lock;
int tries;
volatile int started;
int libc_ex3()
{
int i;
int pid;
/* create a number to search for */
pid = getpid();
printf("Searching for the number = %d...\n", pid);
/* Initialize the mutex lock */
pthread_mutex_init(&lock, NULL);
/* Create the searching threads */
for (started=0; started<NUM_THREADS; started++)
pthread_create(&threads[started], NULL, search, (void *)pid);
/* Wait for (join) all the searching threads */
for (i=0; i<NUM_THREADS; i++)
pthread_join(threads[i], NULL);
printf("It took %d tries to find the number.\n", tries);
/* Exit the program */
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex3, example 5 for libc);
/* This is the cleanup function that is called
when the threads are cancelled */
void print_it(void *arg)
{
int *try = (int *) arg;
pthread_t tid;
/* Get the calling thread's ID */
tid = pthread_self();
/* Print where the thread was in its search when it was cancelled */
printf("Thread %lx was canceled on its %d try.\n", tid, *try);
}
/* This is the search routine that is executed in each thread */
void *search(void *arg)
{
int num = (int) arg;
int i, j, ntries;
pthread_t tid;
/* get the calling thread ID */
tid = pthread_self();
/* use the thread ID to set the seed for the random number generator */
/* Since srand and rand are not thread-safe, serialize with lock */
/* Try to lock the mutex lock --
if locked, check to see if the thread has been cancelled
if not locked then continue */
while (pthread_mutex_trylock(&lock) == EBUSY)
pthread_testcancel();
srand((int)tid);
i = rand() & 0xFFFFFF;
pthread_mutex_unlock(&lock);
ntries = 0;
/* Set the cancellation parameters --
- Enable thread cancellation
- Defer the action of the cancellation */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
while (started < NUM_THREADS)
sched_yield ();
/* Push the cleanup routine (print_it) onto the thread
cleanup stack. This routine will be called when the
thread is cancelled. Also note that the pthread_cleanup_push
call must have a matching pthread_cleanup_pop call. The
push and pop calls MUST be at the same lexical level
within the code */
/* Pass address of `ntries' since the current value of `ntries' is not
the one we want to use in the cleanup function */
pthread_cleanup_push(print_it, (void *)&ntries);
/* Loop forever */
while (1) {
i = (i + 1) & 0xFFFFFF;
ntries++;
/* Does the random number match the target number? */
if (num == i) {
/* Try to lock the mutex lock --
if locked, check to see if the thread has been cancelled
if not locked then continue */
while (pthread_mutex_trylock(&lock) == EBUSY)
pthread_testcancel();
/* Set the global variable for the number of tries */
tries = ntries;
printf("Thread %lx found the number!\n", tid);
/* Cancel all the other threads */
for (j=0; j<NUM_THREADS; j++)
if (threads[j] != tid) pthread_cancel(threads[j]);
/* Break out of the while loop */
break;
}
/* Every 100 tries check to see if the thread has been cancelled. */
if (ntries % 100 == 0) {
pthread_testcancel();
}
}
/* The only way we can get here is when the thread breaks out
of the while loop. In this case the thread that makes it here
has found the number we are looking for and does not need to run
the thread cleanup function. This is why the pthread_cleanup_pop
function is called with a 0 argument; this will pop the cleanup
function off the stack without executing it */
pthread_cleanup_pop(0);
return((void *)0);
}

116
examples/libc/ex4.c Normal file
View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/* Making a library function that uses static variables thread-safe.
Illustrates: thread-specific data, pthread_once(). */
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
/* This is a typical example of a library function that uses
static variables to accumulate results between calls.
Here, it just returns the concatenation of all string arguments
that were given to it. */
#if 0
char * str_accumulate(char * s)
{
static char accu[1024] = { 0 };
strcat(accu, s);
return accu;
}
#endif
/* Of course, this cannot be used in a multi-threaded program
because all threads store "accu" at the same location.
So, we'll use thread-specific data to have a different "accu"
for each thread. */
/* Key identifying the thread-specific data */
static pthread_key_t str_key;
/* "Once" variable ensuring that the key for str_alloc will be allocated
exactly once. */
static pthread_once_t str_alloc_key_once = PTHREAD_ONCE_INIT;
/* Forward functions */
static void str_alloc_key(void);
static void str_alloc_destroy_accu(void * accu);
/* Thread-safe version of str_accumulate */
char * str_accumulate(const char * s)
{
char * accu;
/* Make sure the key is allocated */
pthread_once(&str_alloc_key_once, str_alloc_key);
/* Get the thread-specific data associated with the key */
accu = (char *) pthread_getspecific(str_key);
/* It's initially NULL, meaning that we must allocate the buffer first. */
if (accu == NULL) {
accu = (char *)malloc(1024);
if (accu == NULL) return NULL;
accu[0] = 0;
/* Store the buffer pointer in the thread-specific data. */
pthread_setspecific(str_key, (void *) accu);
printf("Thread %lx: allocating buffer at %p\n", pthread_self(), accu);
}
/* Now we can use accu just as in the non thread-safe code. */
strcat(accu, s);
return accu;
}
/* Function to allocate the key for str_alloc thread-specific data. */
static void str_alloc_key(void)
{
pthread_key_create(&str_key, str_alloc_destroy_accu);
printf("Thread %lx: allocated key %d\n", pthread_self(), str_key);
}
/* Function to free the buffer when the thread exits. */
/* Called only when the thread-specific data is not NULL. */
static void str_alloc_destroy_accu(void * accu)
{
printf("Thread %lx: freeing buffer at %p\n", pthread_self(), accu);
free(accu);
}
/* Test program */
static void *process(void * arg)
{
char *res;
res = str_accumulate("Result of ");
res = str_accumulate((char *) arg);
res = str_accumulate(" thread");
printf("Thread %lx: \"%s\"\n", pthread_self(), res);
return NULL;
}
int libc_ex4()
{
char * res;
pthread_t th1, th2;
// res = str_accumulate("Result of ");
pthread_create(&th1, NULL, process, (void *) "first");
pthread_create(&th2, NULL, process, (void *) "second");
// res = str_accumulate("initial thread");
printf("Thread %lx: \"%s\"\n", pthread_self(), res);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex4, example 4 for libc);

113
examples/libc/ex5.c Normal file
View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/* The classic producer-consumer example, implemented with semaphores.
All integers between 0 and 9999 should be printed exactly twice,
once to the right of the arrow and once to the left. */
#include <stdio.h>
#include "pthread.h"
#include "semaphore.h"
#define BUFFER_SIZE 16
/* Circular buffer of integers. */
struct prodcons {
int buffer[BUFFER_SIZE]; /* the actual data */
int readpos, writepos; /* positions for reading and writing */
sem_t sem_read; /* number of elements available for reading */
sem_t sem_write; /* number of locations available for writing */
};
/* Initialize a buffer */
void init(struct prodcons * b)
{
sem_init(&b->sem_write, 0, BUFFER_SIZE - 1);
sem_init(&b->sem_read, 0, 0);
b->readpos = 0;
b->writepos = 0;
}
/* Store an integer in the buffer */
void put(struct prodcons * b, int data)
{
/* Wait until buffer is not full */
sem_wait(&b->sem_write);
/* Write the data and advance write pointer */
b->buffer[b->writepos] = data;
b->writepos++;
if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
/* Signal that the buffer contains one more element for reading */
sem_post(&b->sem_read);
}
/* Read and remove an integer from the buffer */
int get(struct prodcons * b)
{
int data;
/* Wait until buffer is not empty */
sem_wait(&b->sem_read);
/* Read the data and advance read pointer */
data = b->buffer[b->readpos];
b->readpos++;
if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
/* Signal that the buffer has now one more location for writing */
sem_post(&b->sem_write);
return data;
}
/* A test program: one thread inserts integers from 1 to 10000,
the other reads them and prints them. */
#define OVER (-1)
struct prodcons buffer;
static void *producer(void * data)
{
int n;
for (n = 0; n < 10000; n++) {
printf("%d --->\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
return NULL;
}
static void *consumer(void * data)
{
int d;
while (1) {
d = get(&buffer);
if (d == OVER) break;
printf("---> %d\n", d);
}
return NULL;
}
int libc_ex5(void)
{
pthread_t th_a, th_b;
void * retval;
init(&buffer);
/* Create the threads */
pthread_create(&th_a, NULL, producer, 0);
pthread_create(&th_b, NULL, consumer, 0);
/* Wait until producer and consumer finish. */
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex5, example 5 for libc);

45
examples/libc/ex6.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define usleep rt_thread_sleep
static void *test_thread(void *v_param) {
return NULL;
}
int libc_ex6(void) {
unsigned long count;
setvbuf(stdout, NULL, _IONBF, 0);
for (count = 0; count < 2000; ++count) {
pthread_t thread;
int status;
status = pthread_create(&thread, NULL, test_thread, NULL);
if (status != 0) {
printf("status = %d, count = %lu: %s\n", status, count, strerror(
errno));
return 1;
} else {
printf("count = %lu\n", count);
}
/* pthread_detach (thread); */
pthread_join(thread, NULL);
usleep(10);
}
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex6, example 6 for libc);

109
examples/libc/ex7.c Normal file
View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/* ex7
*
* Test case that illustrates a timed wait on a condition variable.
*/
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#define usleep rt_thread_sleep
/* Our event variable using a condition variable contruct. */
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int flag;
} event_t;
/* Global event to signal main thread the timeout of the child thread. */
event_t main_event;
static void *test_thread(void *ms_param) {
int status = 0;
event_t foo;
struct timespec time;
struct timeval now;
long ms = (long) ms_param;
/* initialize cond var */
pthread_cond_init(&foo.cond, NULL);
pthread_mutex_init(&foo.mutex, NULL);
foo.flag = 0;
/* set the time out value */
printf("waiting %ld ms ...\n", ms);
gettimeofday(&now, NULL);
time.tv_sec = now.tv_sec + ms / 1000 + (now.tv_usec + (ms % 1000) * 1000)
/ 1000000;
time.tv_nsec = ((now.tv_usec + (ms % 1000) * 1000) % 1000000) * 1000;
/* Just use this to test the time out. The cond var is never signaled. */
pthread_mutex_lock(&foo.mutex);
while (foo.flag == 0 && status != ETIMEDOUT) {
status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &time);
}
pthread_mutex_unlock(&foo.mutex);
/* post the main event */
pthread_mutex_lock(&main_event.mutex);
main_event.flag = 1;
pthread_cond_signal(&main_event.cond);
pthread_mutex_unlock(&main_event.mutex);
/* that's it, bye */
return (void*) status;
}
int libc_ex7(void) {
unsigned long count;
setvbuf(stdout, NULL, _IONBF, 0);
/* initialize main event cond var */
pthread_cond_init(&main_event.cond, NULL);
pthread_mutex_init(&main_event.mutex, NULL);
main_event.flag = 0;
for (count = 0; count < 20; ++count) {
pthread_t thread;
int status;
/* pass down the milli-second timeout in the void* param */
status = pthread_create(&thread, NULL, test_thread, (void*) (count
* 100));
if (status != 0) {
printf("status = %d, count = %lu: %s\n", status, count, strerror(
errno));
return 1;
} else {
/* wait for the event posted by the child thread */
pthread_mutex_lock(&main_event.mutex);
while (main_event.flag == 0) {
pthread_cond_wait(&main_event.cond, &main_event.mutex);
}
main_event.flag = 0;
pthread_mutex_unlock(&main_event.mutex);
printf("count = %lu\n", count);
}
usleep(10);
}
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex7, example 7 for libc);

520
examples/libc/file.c Normal file
View file

@ -0,0 +1,520 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
const char* text = "this is a test string\n";
void libc_fstat()
{
int fd;
struct stat s;
fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0);
if (fd < 0)
{
printf("open failed\n");
return;
}
write(fd, text, strlen(text) + 1);
printf("begin: %d\n", lseek(fd, 0, SEEK_SET));
printf("end: %d\n", lseek(fd, 0, SEEK_END));
printf("fstat result: %d\n", fstat(fd, &s));
close(fd);
}
FINSH_FUNCTION_EXPORT(libc_fstat, fstat test for libc);
void libc_lseek()
{
int fd;
fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0);
if (fd < 0)
{
printf("open failed\n");
return;
}
write(fd, text, strlen(text) + 1);
printf("begin: %d\n", lseek(fd, 0, SEEK_SET));
printf("end: %d\n", lseek(fd, 0, SEEK_END));
close(fd);
}
FINSH_FUNCTION_EXPORT(libc_lseek, lseek test for libc);
void sleep(int tick)
{
rt_thread_sleep(tick);
}
int libc_fseek(void)
{
const char *tmpdir;
char *fname;
int fd;
FILE *fp;
const char outstr[] = "hello world!\n";
char strbuf[sizeof outstr];
char buf[200];
struct stat st1;
struct stat st2;
int result = 0;
tmpdir = getenv("TMPDIR");
if (tmpdir == NULL || tmpdir[0] == '\0')
tmpdir = "/tmp";
asprintf(&fname, "%s/tst-fseek.XXXXXX", tmpdir);
if (fname == NULL)
{
fprintf(stderr, "cannot generate name for temporary file: %s\n",
strerror(errno));
return 1;
}
/* Create a temporary file. */
fd = mkstemp(fname);
if (fd == -1)
{
fprintf(stderr, "cannot open temporary file: %s\n", strerror(errno));
return 1;
}
fp = fdopen(fd, "w+");
if (fp == NULL)
{
fprintf(stderr, "cannot get FILE for temporary file: %s\n", strerror(
errno));
return 1;
}
setbuffer(fp, strbuf, sizeof(outstr) - 1);
if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: write error\n", __LINE__);
result = 1;
goto out;
}
/* The EOF flag must be reset. */
if (fgetc(fp) != EOF)
{
printf("%d: managed to read at end of file\n", __LINE__);
result = 1;
}
else if (!feof(fp))
{
printf("%d: EOF flag not set\n", __LINE__);
result = 1;
}
if (fseek(fp, 0, SEEK_CUR) != 0)
{
printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
result = 1;
}
else if (feof(fp))
{
printf("%d: fseek() didn't reset EOF flag\n", __LINE__);
result = 1;
}
/* Do the same for fseeko(). */
if (fgetc(fp) != EOF)
{
printf("%d: managed to read at end of file\n", __LINE__);
result = 1;
}
else if (!feof(fp))
{
printf("%d: EOF flag not set\n", __LINE__);
result = 1;
}
if (fseeko(fp, 0, SEEK_CUR) != 0)
{
printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
result = 1;
}
else if (feof(fp))
{
printf("%d: fseek() didn't reset EOF flag\n", __LINE__);
result = 1;
}
/* Go back to the beginning of the file: absolute. */
if (fseek(fp, 0, SEEK_SET) != 0)
{
printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
result = 1;
}
else if (fflush(fp) != 0)
{
printf("%d: fflush() failed\n", __LINE__);
result = 1;
}
else if (lseek(fd, 0, SEEK_CUR) != 0)
{
int pos = lseek(fd, 0, SEEK_CUR);
printf("%d: lseek() returned different position, pos %d\n", __LINE__,
pos);
result = 1;
}
else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: fread() failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
{
printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
result = 1;
}
/* Now with fseeko. */
if (fseeko(fp, 0, SEEK_SET) != 0)
{
printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
result = 1;
}
else if (fflush(fp) != 0)
{
printf("%d: fflush() failed\n", __LINE__);
result = 1;
}
else if (lseek(fd, 0, SEEK_CUR) != 0)
{
printf("%d: lseek() returned different position\n", __LINE__);
result = 1;
}
else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: fread() failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
{
printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
result = 1;
}
/* Go back to the beginning of the file: relative. */
if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0)
{
printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
result = 1;
}
else if (fflush(fp) != 0)
{
printf("%d: fflush() failed\n", __LINE__);
result = 1;
}
else if (lseek(fd, 0, SEEK_CUR) != 0)
{
printf("%d: lseek() returned different position\n", __LINE__);
result = 1;
}
else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: fread() failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
{
printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
result = 1;
}
/* Now with fseeko. */
if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0)
{
printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
result = 1;
}
else if (fflush(fp) != 0)
{
printf("%d: fflush() failed\n", __LINE__);
result = 1;
}
else if (lseek(fd, 0, SEEK_CUR) != 0)
{
printf("%d: lseek() returned different position\n", __LINE__);
result = 1;
}
else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: fread() failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
{
printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
result = 1;
}
/* Go back to the beginning of the file: from the end. */
if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0)
{
printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
result = 1;
}
else if (fflush(fp) != 0)
{
printf("%d: fflush() failed\n", __LINE__);
result = 1;
}
else if (lseek(fd, 0, SEEK_CUR) != 0)
{
printf("%d: lseek() returned different position\n", __LINE__);
result = 1;
}
else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: fread() failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
{
printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
result = 1;
}
/* Now with fseeko. */
if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0)
{
printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
result = 1;
}
else if (fflush(fp) != 0)
{
printf("%d: fflush() failed\n", __LINE__);
result = 1;
}
else if (lseek(fd, 0, SEEK_CUR) != 0)
{
printf("%d: lseek() returned different position\n", __LINE__);
result = 1;
}
else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: fread() failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
{
printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
result = 1;
}
if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: write error 2\n", __LINE__);
result = 1;
goto out;
}
if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: write error 3\n", __LINE__);
result = 1;
goto out;
}
if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: write error 4\n", __LINE__);
result = 1;
goto out;
}
if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
{
printf("%d: write error 5\n", __LINE__);
result = 1;
goto out;
}
if (fputc('1', fp) == EOF || fputc('2', fp) == EOF)
{
printf("%d: cannot add characters at the end\n", __LINE__);
result = 1;
goto out;
}
/* Check the access time. */
if (fstat(fd, &st1) < 0)
{
printf("%d: fstat64() before fseeko() failed\n\n", __LINE__);
result = 1;
}
else
{
sleep(1);
if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_CUR) != 0)
{
printf("%d: fseek() after write characters failed\n", __LINE__);
result = 1;
goto out;
}
else
{
time_t t;
/* Make sure the timestamp actually can be different. */
sleep(1);
t = time(NULL);
if (fstat(fd, &st2) < 0)
{
printf("%d: fstat64() after fseeko() failed\n\n", __LINE__);
result = 1;
}
if (st1.st_ctime >= t)
{
printf("%d: st_ctime not updated\n", __LINE__);
result = 1;
}
if (st1.st_mtime >= t)
{
printf("%d: st_mtime not updated\n", __LINE__);
result = 1;
}
if (st1.st_ctime >= st2.st_ctime)
{
printf("%d: st_ctime not changed\n", __LINE__);
result = 1;
}
if (st1.st_mtime >= st2.st_mtime)
{
printf("%d: st_mtime not changed\n", __LINE__);
result = 1;
}
}
}
if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2
* (sizeof(outstr) - 1))
{
printf("%d: reading 2 records plus bits failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp(
&buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2
* (sizeof(outstr) - 1)] != '1' || buf[2 * (sizeof(outstr) - 1) + 1]
!= '2')
{
printf("%d: reading records failed\n", __LINE__);
result = 1;
}
else if (ungetc('9', fp) == EOF)
{
printf("%d: ungetc() failed\n", __LINE__);
result = 1;
}
else if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_END) != 0)
{
printf("%d: fseek after ungetc failed\n", __LINE__);
result = 1;
}
else if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2
* (sizeof(outstr) - 1))
{
printf("%d: reading 2 records plus bits failed\n", __LINE__);
result = 1;
}
else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp(
&buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2
* (sizeof(outstr) - 1)] != '1')
{
printf("%d: reading records for the second time failed\n", __LINE__);
result = 1;
}
else if (buf[2 * (sizeof(outstr) - 1) + 1] == '9')
{
printf("%d: unget character not ignored\n", __LINE__);
result = 1;
}
else if (buf[2 * (sizeof(outstr) - 1) + 1] != '2')
{
printf("%d: unget somehow changed character\n", __LINE__);
result = 1;
}
fclose(fp);
fp = fopen(fname, "r");
if (fp == NULL)
{
printf("%d: fopen() failed\n\n", __LINE__);
result = 1;
}
else if (fstat(fileno(fp), &st1) < 0)
{
printf("%d: fstat64() before fseeko() failed\n\n", __LINE__);
result = 1;
}
else if (fseeko(fp, 0, SEEK_END) != 0)
{
printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
result = 1;
}
else if (ftello(fp) != st1.st_size)
{
printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
(size_t) st1.st_size, (size_t) ftello(fp));
result = 1;
}
else
printf("%d: SEEK_END works\n", __LINE__);
if (fp != NULL)
fclose(fp);
fp = fopen(fname, "r");
if (fp == NULL)
{
printf("%d: fopen() failed\n\n", __LINE__);
result = 1;
}
else if (fstat(fileno(fp), &st1) < 0)
{
printf("%d: fstat64() before fgetc() failed\n\n", __LINE__);
result = 1;
}
else if (fgetc(fp) == EOF)
{
printf("%d: fgetc() before fseeko() failed\n\n", __LINE__);
result = 1;
}
else if (fseeko(fp, 0, SEEK_END) != 0)
{
printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
result = 1;
}
else if (ftello(fp) != st1.st_size)
{
printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
(size_t) st1.st_size, (size_t) ftello(fp));
result = 1;
}
else
printf("%d: SEEK_END works\n", __LINE__);
if (fp != NULL)
fclose(fp);
out: unlink(fname);
return result;
}
FINSH_FUNCTION_EXPORT(libc_fseek, lseek test for libc);

60
examples/libc/memory.c Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <sys/errno.h>
static int errors = 0;
static void merror(const char *msg)
{
++errors;
printf("Error: %s\n", msg);
}
int libc_mem(void)
{
void *p;
int save;
errno = 0;
p = malloc(-1);
save = errno;
if (p != NULL)
merror("malloc (-1) succeeded.");
if (p == NULL && save != ENOMEM)
merror("errno is not set correctly");
p = malloc(10);
if (p == NULL)
merror("malloc (10) failed.");
/* realloc (p, 0) == free (p). */
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
p = malloc(0);
if (p == NULL)
{
printf("malloc(0) returns NULL\n");
}
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
return errors != 0;
}
FINSH_FUNCTION_EXPORT(libc_mem, memory test for libc);

129
examples/libc/mq.c Normal file
View file

@ -0,0 +1,129 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <mqueue.h>
#define MQ_NAME_1 "testmsg1"
#define MQ_NAME_2 "testmsg2"
#define MSG_SIZE 128
#define MAX_MSG 3
const char *s_msg_ptr[] = {"msg test 1", "msg test 2", "msg test 3"};
char r_msg_ptr_1[MAX_MSG][MSG_SIZE];
char r_msg_ptr_2[MAX_MSG][MSG_SIZE];
pthread_t send1, send2, rev1, rev2;
int * send_1(void * mq)
{
int i;
mqd_t mq1 = *(mqd_t *)mq;
printf("Enter into send_1 \n");
for (i = 0; i < MAX_MSG; i++ ) {
if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) {
perror("mq_send doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]);
}
pthread_exit((void *)0);
}
int * send_2(void * mq)
{
int i;
mqd_t mq2 = *(mqd_t *)mq;
printf("Enter into send_2 \n");
for (i = 0; i < MAX_MSG; i++ ) {
if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) {
perror("mq_send doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]);
}
pthread_exit((void *)0);
}
int * receive_1(void * mq)
{
int i;
mqd_t mq1 = *(mqd_t *)mq;
printf("Enter into receive_1 \n");
for (i = 0; i< MAX_MSG; i++) {
if ( -1 == mq_receive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL) ) {
perror("mq_receive doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] receive '%s' in thread receive_1. \n", i+1, r_msg_ptr_1[i]);
}
pthread_exit((void *)0);
}
int * receive_2(void * mq)
{
int i;
mqd_t mq2 = *(mqd_t *)mq;
printf("Enter into receive_2 \n");
for (i = 0; i< MAX_MSG; i++) {
if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) {
perror("mq_receive doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]);
}
pthread_exit((void *)0);
}
int libc_mq()
{
mqd_t mq1 = 0, mq2 = 0;
struct mq_attr mqstat;
int oflag = O_CREAT|O_RDWR;
memset(&mqstat, 0, sizeof(mqstat));
mqstat.mq_maxmsg = MAX_MSG;
mqstat.mq_msgsize = MSG_SIZE;
mqstat.mq_flags = 0;
if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) {
printf("mq_open doesn't return success \n");
return -1;
}
if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) {
printf("mq_open doesn't return success \n");
return -1;
}
pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1);
pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2);
pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1);
pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2);
pthread_join(send1, NULL);
pthread_join(send2, NULL);
pthread_join(rev1, NULL);
pthread_join(rev2, NULL);
mq_close(mq1);
mq_close(mq2);
mq_unlink(MQ_NAME_1);
mq_unlink(MQ_NAME_2);
printf("PASSED\n");
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_mq, posix mqueue test);

210
examples/libc/printf.c Normal file
View file

@ -0,0 +1,210 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <finsh.h>
char * format[] = {
"%",
"%0.",
"%.0",
"%+0.",
"%+.0",
"%.5",
"%+.5",
"%2.5",
"%22.5",
"%022.5",
"%#022.5",
"%-#022.5",
"%+#022.5",
"%-22.5",
"%+22.5",
"%--22.5",
"%++22.5",
"%+-22.5",
"%-+22.5",
"%-#022.5",
"%-#22.5",
"%-2.22",
"%+2.22",
"%-#02.22",
"%-#2.22",
"%-1.5",
"%1.5",
"%-#01.5",
"%-#1.5",
"%-#.5",
"%-#1.",
"%-#.",
NULL
};
static void
intchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0);
(void) printf("\", \"");
(void) printf(fmt, 123);
(void) printf("\", \"");
(void) printf(fmt, -18);
(void) printf("\"\n");
}
static void
fltchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0.0);
(void) printf("\", \"");
(void) printf(fmt, 123.0001);
(void) printf("\", \"");
(void) printf(fmt, -18.0002301);
(void) printf("\"\n");
}
int printf_test()
{
char buf[256];
int i;
printf("%s\n\n", "# vim:syntax=off:");
/* integers */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "d");
intchk(buf);
}
/* floats */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "f");
fltchk(buf);
}
/* hexa */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "x");
intchk(buf);
}
printf("#%.4x %4x#\n", 4, 88);
printf("#%4x#\n",4);
printf("#%#22.8x#\n",1234567);
printf("#%+2i#\n",18);
printf("#%i#\n",18);
printf("#%llu#\n",4294967297ULL);
printf("#%#x#\n",44444);
printf("#%-8i#\n",33);
printf("#%i#\n",18);
printf("#%d#\n",18);
printf("#%u#\n",18);
printf("#%lu#\n",18);
printf("#%li#\n",18);
printf("#%-+#06d#\n", -123);
printf("#%-+#6d#\n", -123);
printf("#%+#06d#\n", -123);
printf("#%06d#\n", -123);
printf("#%+15s#\n","ABCDEF");
/* from ncurses make_keys */
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("%*.*f\n", 0, 16, 0.0);
printf("%*.*f\n", 16, 16, 0.0);
printf("%*.*f\n", 2, 2, -0.0);
printf("%*.*f\n", 20, 0, -123.123);
printf("%*.*f\n", 10, 0, +123.123);
i = printf("\"%s\"\n","A");
printf("%i\n", i);
/* from glibc's tst-printf.c */
{
char buf[20];
char buf2[512];
int i;
printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf),
buf);
memset(buf2,0,sizeof(buf));
i=snprintf(buf2, 256, "%.9999u", 10);
printf("%i %i\n",i,strlen(buf2));
printf ("snprintf (\"%%.999999u\", 10) == %d\n",
snprintf(buf2, sizeof(buf2), "%.999999u", 10));
}
return 0;
}
void libc_printf()
{
printf("stdout test!!\n");
fprintf(stdout, "fprintf test!!\n");
fprintf(stderr, "fprintf test!!\n");
puts("puts test!!\n");
putc('1', stderr);
putc('2', stderr);
putc('\n', stderr);
printf_test();
}
FINSH_FUNCTION_EXPORT(libc_printf, printf test in libc);
void libc_dprintf()
{
int fd;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
dprintf(fd, "fd:%d printf test!!\n", fd);
close(fd);
}
}
FINSH_FUNCTION_EXPORT(libc_dprintf, dprintf test);
void libc_fdopen()
{
int fd;
FILE* fp;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
fp = fdopen(fd, "w");
fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp));
fclose(fp);
}
}
FINSH_FUNCTION_EXPORT(libc_fdopen, fdopen test);

47
examples/libc/rand.c Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_rand(void)
{
int i1, i2;
int j1, j2;
/* The C standard says that "If rand is called before any calls to
srand have been made, the same sequence shall be generated as
when srand is first called with a seed value of 1." */
i1 = rand();
i2 = rand();
srand(1);
j1 = rand();
j2 = rand();
if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0)
{
puts("Test FAILED!");
}
if (j1 == i1 && j2 == i2)
{
puts("Test succeeded.");
return 0;
}
else
{
if (j1 != i1)
printf("%d != %d\n", j1, i1);
if (j2 != i2)
printf("%d != %d\n", j2, i2);
puts("Test FAILED!");
return 1;
}
}
FINSH_FUNCTION_EXPORT(libc_rand, rand test for libc);

74
examples/libc/sem.c Normal file
View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
static sem_t sema;
static void* other_thread()
{
printf("other_thread here!\n");
sleep(1);
while (1)
{
printf("other_thread: sem_post...\n");
if(sem_post(&sema) == -1)
printf("sem_post failed\n");
sleep(1);
}
printf("other_thread dies!\n");
pthread_exit(0);
}
static void test_thread(void* parameter)
{
pthread_t tid;
printf("main thread here!\n");
printf("sleep 5 seconds...");
sleep(5);
printf("done\n");
sem_init(&sema, 0, 0);
/* create the "other" thread */
if(pthread_create(&tid, 0, &other_thread, 0)!=0)
/* error */
printf("pthread_create OtherThread failed.\n");
else
printf("created OtherThread=%x\n", tid);
/* let the other thread run */
while (1)
{
printf("Main: sem_wait...\n");
if(sem_wait(&sema) == -1)
printf("sem_wait failed\n");
printf("Main back.\n\n");
}
pthread_exit(0);
}
#include <finsh.h>
void libc_sem()
{
rt_thread_t tid;
tid = rt_thread_create("semtest", test_thread, RT_NULL,
2048, 20, 5);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
}
FINSH_FUNCTION_EXPORT(libc_sem, posix semaphore test);

View file

@ -0,0 +1,351 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-12-06 JasonJia first version
*/
#include <rtthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/time.h>
#define JOINT(x,y) x##y
#define B(x) JOINT(B,x)
#define Default_baud_rate 115200
#define Default_parity 'n'
#define BUFFER_SIZE 64
struct termios_test_s
{
int baud_rate;
const char *dev;
};
static struct termios_test_s term_param;
static int _check_baud_rate(int baud_rate)
{
#define BAUD_RATE(x) \
{\
if(x==baud_rate) \
{\
rt_kprintf("%d baud rate\n",baud_rate);\
return JOINT(B,x);\
}\
}
BAUD_RATE(110);
BAUD_RATE(200);
BAUD_RATE(300);
BAUD_RATE(600);
BAUD_RATE(1200);
BAUD_RATE(1800);
BAUD_RATE(2400);
BAUD_RATE(4800);
BAUD_RATE(9600);
BAUD_RATE(19200);
BAUD_RATE(38400);
BAUD_RATE(57600);
BAUD_RATE(115200);
BAUD_RATE(230400);
BAUD_RATE(460800);
BAUD_RATE(921600);
rt_kprintf("%d is not support,use default %d value.\n",baud_rate,Default_baud_rate);
return B(Default_baud_rate);
}
int open_comm(const char *name)
{
int fd;
fd = open(name, O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
if(fd == -1)
{
rt_kprintf("Open %s fail.\n",name);
return -1;
}
else
{
rt_kprintf("Open %s success,fd:%d\n",name,fd);
}
return fd;
}
void close_comm(int fd)
{
if(fd != -1)
{
close(fd);
}
}
void config_comm(int fd, int speed_baud_rate, char parity, int data_bits, int stop_bits)
{
int valid_baud_rate = 0;
struct termios new_tc;
memset(&new_tc, 0x00, sizeof(struct termios));
valid_baud_rate = _check_baud_rate(speed_baud_rate);
new_tc.c_cflag |= (CLOCAL | CREAD);//Enable in default.
/*
*Set baud rate. e.g B115200 is 115200 bauds.
*/
cfsetispeed(&new_tc, valid_baud_rate);//input speed
cfsetospeed(&new_tc, valid_baud_rate);//output speed
/*
*Set parity.
*/
switch(parity)
{
case 'n':
case 'N':
new_tc.c_cflag &= ~PARENB; //Disable parity.
break;
case 'o':
case 'O':
new_tc.c_cflag |= PARENB; //Enable parity.
new_tc.c_cflag |= PARODD; //Odd parity.
break;
case 'e':
case 'E':
new_tc.c_cflag |= PARENB; //Enable parity.
new_tc.c_cflag &= ~PARODD; //even parity.
break;
}
/*
*Set data bits.
*/
new_tc.c_cflag &= ~CSIZE;
switch(data_bits)
{
case 5:
break;
case 6:
break;
case 7:
new_tc.c_cflag |= CS7;
break;
case 8:
new_tc.c_cflag |= CS8;
break;
}
/*
*Set stop bits.
*/
(stop_bits == 2)?(new_tc.c_cflag |= CSTOPB):(new_tc.c_cflag &= ~ CSTOPB);
tcflush(fd,TCIFLUSH);
//new_tc.c_cc[VTIME] = 0;
//new_tc.c_cc[VMIN] = 1;
if( tcsetattr(fd, TCSANOW, &new_tc) != 0)
{
rt_kprintf("Set port config fail!\n");
}
}
int recv_comm(int fd, unsigned char *buffer, rt_size_t size, struct timeval *timeout)
{
struct timeval t;
int ret = 0;
rt_size_t drv_recved = 0;
int recved = 0, need = size;
int timeout_cnt = 0;
unsigned char *c = RT_NULL;
fd_set readSet;
RT_ASSERT(RT_NULL != buffer);
if(fd == -1)
{
return -1;
}
t.tv_sec = 0;
t.tv_usec = 100000;
if(RT_NULL == timeout)
{
/* Wait forever approximate, it's a large time. */
timeout_cnt = 0xffffffff;
}
else
{
timeout_cnt = (timeout->tv_sec * 1000 * 1000 + timeout->tv_usec)/(t.tv_sec * 1000 * 1000 + t.tv_usec);
}
while(1)
{
FD_ZERO(&readSet);
FD_SET(fd, &readSet);
ret = select(fd+1,&readSet,RT_NULL,RT_NULL,&t);
if(ret < 0)
{
rt_kprintf("select error %d\n",ret);
break;
}
else if(ret == 0)
{
/* timeout */
timeout_cnt--;
if(timeout_cnt == 0)
{
rt_kprintf("need %d data in timeout %d ms,but only %d recved.\n",
size,
timeout->tv_sec * 1000 + timeout->tv_usec / 1000,
recved);
recved = 0;
break;
}
}
else
{
if(FD_ISSET(fd, &readSet))
{
c = &buffer[size - need];
ioctl(fd, FIONREAD, &drv_recved);
/* check poll and ioctl */
RT_ASSERT(drv_recved != 0);
drv_recved = (drv_recved > need ? need : drv_recved);
recved = read(fd, c, drv_recved);
if(recved != drv_recved)
{
rt_kprintf("fatal error %s(%d).\n",__FUNCTION__,__LINE__);
RT_ASSERT(0);
recved = 0;
break;
}
need -= recved;
if(need)
{
continue;
}
else if (need == 0)
{
recved = size;
break;
}
else
{
rt_kprintf("fatal error %s(%d).\n",__FUNCTION__,__LINE__);
RT_ASSERT(0);
}
}
}
}
return recved;
}
int send_comm(int fd, const unsigned char *buffer, rt_size_t size)
{
RT_ASSERT(RT_NULL != buffer);
if(fd == -1)
{
return -1;
}
//serial framework does not support poll out now
write(fd, buffer, size);
return 0;
}
int flush_comm(int fd)
{
if(fd == -1)
{
return -1;
}
tcflush(fd,TCIFLUSH);
return 0;
}
void termios_test_entry(void *p)
{
int len = 0;
int fd = -1;
unsigned char *pBuf = RT_NULL;
struct termios_test_s *pTerm = (struct termios_test_s *)p;
if((fd = open_comm(pTerm->dev)) == -1)
{
rt_kprintf("Check the device name...\n");
return;
}
pBuf = (unsigned char *)rt_malloc(BUFFER_SIZE);
RT_ASSERT(pBuf != RT_NULL);
memset(pBuf, 0x00, BUFFER_SIZE);
config_comm(fd, pTerm->baud_rate, Default_parity, 8, 1);
flush_comm(fd);
rt_kprintf("Block recv 10 bytes.\n");
/* Block recv 10 bytes */
len = recv_comm(fd, pBuf, 10, RT_NULL);
rt_kprintf("Recv:%s\n", pBuf);
send_comm(fd, pBuf, len);
rt_kprintf("Termios test exit.\n");
close_comm(fd);
rt_free(pBuf);
pBuf = RT_NULL;
}
int termios_test(int argc, char **argv)
{
rt_thread_t tid;
if(argc < 2)
{
rt_kprintf("Please input device name...\n");
return -1;
}
term_param.dev = argv[1];
term_param.baud_rate = ((argc >= 3) ? atoi(argv[2]) : Default_baud_rate);
tid = rt_thread_create("termtest",
termios_test_entry, (void *)&term_param,
512, RT_THREAD_PRIORITY_MAX/3, 20);
if (tid != RT_NULL)
rt_thread_startup(tid);
return 0;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
#ifdef RT_USING_FINSH
MSH_CMD_EXPORT_ALIAS(termios_test, termtest, e.g: termtest /dev/uart4 115200);
#endif /* RT_USING_FINSH */
#endif /* RT_USING_FINSH */

27
examples/libc/time.c Normal file
View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-11-17 Bernard first version
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int speed()
{
int i;
time_t t;
printf("%d\n", time(0));
for (i = 0; i < 10000000; ++i)
t = time(0);
printf("%d\n", time(0));
return 0;
}
FINSH_FUNCTION_EXPORT(speed, speed test);