diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 4eb1651..51abdaa 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -8,7 +8,8 @@ "defines": [ "_DEBUG", "UNICODE", - "_UNICODE" + "_UNICODE", + "LINUX" ], "windowsSdkVersion": "10.0.22621.0", "compilerPath": "C:/cygwin64/bin/gcc.exe", diff --git a/.vscode/settings.json b/.vscode/settings.json index 411469a..5352dcf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,8 @@ "test1.h": "c", "stdint.h": "c", "exception.h": "c", - "mythread.h": "c" + "mythread.h": "c", + "ipc.h": "c", + "errno.h": "c" } } \ No newline at end of file diff --git a/main.c b/main.c index 023b314..476aeb2 100644 --- a/main.c +++ b/main.c @@ -5,10 +5,11 @@ #include "soft/exception.h" #include "soft/mythread.h" #include "unistd.h" +#include "soft/debug.h" int thread_fun(void *t){ - printf("run in thread_fun.\n"); + DBG_INFO("run in thread_fun.\n"); while(1){ sleep(5); @@ -22,8 +23,8 @@ int thread_fun(void *t){ void SystemInit(); extern char **environ; int main(int argc,char *argv[]){ - int id; - printf("hello world.\n"); + debug_init(NULL); + DBG_INFO("hello world.%ld\n",(size_t)pthread_self()); @@ -33,8 +34,8 @@ int main(int argc,char *argv[]){ // } // printf("a+b=%d",test_add(3,5)); - id=myth_create(thread_fun,NULL); - id=myth_create(NULL,NULL); + myth_create(thread_fun,NULL); + myth_create(NULL,NULL); // sleep(10); myth_join(); } @@ -56,11 +57,11 @@ typedef void (*slot_fun_def)(size_t a,size_t b,size_t c,size_t d,size_t e,size_t void funptr_test(){ - printf("print from funptr_test fun.\n"); + DBG_INFO("print from funptr_test fun.\n"); } void add_test(int a,int b,void (*f)()){ - printf("add_fun:%d+%d=%d\n",a,b,a+b); + DBG_INFO("add_fun:%d+%d=%d\n",a,b,a+b); f(); } diff --git a/make.py b/make.py index 69c5108..1b5a398 100644 --- a/make.py +++ b/make.py @@ -28,17 +28,19 @@ CSRC = [] CINC = ['-Isoft'] -CDEF = ["-DTEST"] +CDEF = ["-DTEST","-DLINUX"] ASRC = [] BUILD_DIR = 'build' -TARGET = 'hello' +TARGET = 'hello.exe' # CFLAG = ["-Wall -pedantic -specs=nano.specs -mcpu=cortex-m3 -mthumb -lc -lm -lnosys -Og -Tstm32_boot.ld", # f"-Wl,-Map={BUILD_DIR}/{TARGET}.map,--cref -Wl,--gc-sections"] -CFLAG = ["-Wall -pedantic -g"] +# -pedantic 这一项是ISO语法检验 +CFLAG = ["-Wall -g"] + # 找到指定后缀的文件 def find_type(path:str,fix:list[str]): @@ -82,6 +84,7 @@ def tran_path(path:str): # 判断是否需要重新生成 def check_rebuild(dst:str,src:list[str]): + # print(f"src:{src}") if(not os.path.exists(dst)): return True dst_time=os.path.getmtime(dst) @@ -91,6 +94,9 @@ def check_rebuild(dst:str,src:list[str]): src_time.sort() if(src_time[-1]>dst_time): return True + # for item in src_time: + # if(item>dst_time): + # return True return False @@ -98,7 +104,14 @@ def check_rebuild(dst:str,src:list[str]): # 读取.d文件,返回依赖文件列表 def read_depend_files(name:str): with open(name) as f: - t=f.readline() + lines=f.readlines() + t='' + for line in lines: + line=line.strip() + if(line[-1]=='\\'): + t+=line[:-1] + else: + t+=line t=t.split(':')[-1].strip() t=t.split(' ') # print(f"依赖列表{t}") @@ -118,7 +131,8 @@ def build_depend(src:list[str]): ret=os.system(cmd) if(ret): exit() - + else: + print(f"{i} 没有更新源文件") # 生成中间文件 def build_object(src:list[str]): @@ -135,9 +149,13 @@ def build_object(src:list[str]): cd=os.path.join(BUILD_DIR,cd) if(check_rebuild(dst,read_depend_files(cd))): cmd=f"{CC} -c {i} -o {dst} {flags}" + else: + print(f"{i} 没有更新依赖关系") elif(file_type in ['s','S','asm','ASM']): if(check_rebuild(dst,[i])): cmd=f"{AS} -c {i} -o {dst} {flags}" + else: + print(f"{i} 没有更新依赖关系") if(len(cmd)>0): print(cmd) ret=os.system(cmd) @@ -160,13 +178,13 @@ def build_target(src:list[str]): if(ret): exit() else: - print("已是最新,无需要重新生成的目标") + print(f"{dst} 没有更新的链接文件") def main(): global CSRC global ASRC - CSRC+=find_type('./',['c','C']) + CSRC+=find_type('.\\',['c','C']) # ASRC+=find_type('./',['s','S','asm','ASM']) if(not os.path.exists(BUILD_DIR)): @@ -176,7 +194,7 @@ def main(): build_depend(CSRC) print("生成对象文件") build_object(CSRC) - build_object(ASRC) + # build_object(ASRC) print("生成目标文件") build_target(CSRC+ASRC) # os.system(f"{HEX} {BUILD_DIR}/{TARGET} {BUILD_DIR}/{TARGET}.hex") diff --git a/soft/debug.c b/soft/debug.c new file mode 100644 index 0000000..612186a --- /dev/null +++ b/soft/debug.c @@ -0,0 +1,162 @@ + +#include "stdio.h" +#include "stdarg.h" +#include "debug.h" +#include "string.h" +#include +#include +#include +#include "errno.h" + +#define CONSOLEBUF_SIZE 1024 + + +#ifdef LINUX +union semun{ + int val; /* Value for SETVAL */ + struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ + unsigned short *array; /* Array for GETALL, SETALL */ + struct seminfo *__buf; /* Buffer for IPC_INFO + (Linux-specific) */ +}; + + + +void _sem_take(int semid)//寰楀埌閽ュ寵 +{ + struct sembuf sop; + sop.sem_num = 0;//鎺у埗绗竴涓俊鍙烽噺 + sop.sem_op = -1;//閽ュ寵鏁伴噺鍑忎竴6 + sop.sem_flg = SEM_UNDO; + semop(semid,&sop,1); +} + +void _sem_relase(int semid)//鏀惧洖閽ュ寵 +{ + struct sembuf sop; + sop.sem_num = 0; + sop.sem_op = 1; + sop.sem_flg = SEM_UNDO; + semop(semid,&sop,1); +} + +int _sem_init(){ + key_t key; + int mutex; + key = ftok(".",5345); + printf("sem init, key=%llu\n",key); + mutex = semget(key,1,IPC_CREAT);//鍒涘缓淇″彿閲 + printf("sem init, mutex=%d\n",mutex); + if(mutex<=0){ + printf("%d\n",errno); + } + union semun set; + set.val = 1;//閽ュ寵鏁伴噺涓0 + semctl(mutex,0,SETVAL,set); + return mutex; +} + +#endif + +#ifdef RT_THREAD + +#include "rtthread.h" + +#endif + + +typedef struct{ + int inited; + #ifdef RT_THREAD + struct rt_mutex mutex; + #endif + #ifdef LINUX + int mutex; + #endif + dbg_dev *dev; +}self_def; + +static self_def g_data; + + + +static int dev_init(){ + return 0; +} +static int dev_write(const uint8_t *data,size_t len){ + size_t rb; + rb=fwrite(data,sizeof(uint8_t),len,stdout); + return (int)rb; +} +static dbg_dev g_dev_default={ + .init=dev_init, + .write=dev_write, +}; + + + + +int debug_init(dbg_dev *dev) +{ + self_def *self=&g_data; + if(dev==NULL){ + dev=&g_dev_default; + } + if(self->inited==0) + { + #ifdef RT_THREAD + rt_mutex_init(&self->mutex,"debug_mutex",RT_IPC_FLAG_FIFO); + #endif + #ifdef LINUX + self->mutex=_sem_init(); + #endif + self->dev=dev; + self->dev->init(); + self->dev->write((const uint8_t *)"\r\n",2); + self->inited=1; + DBG_LOG("debug inited.\r\n"); + } + return 0; +} + + +void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...) +{ + self_def *self=&g_data; + if(self->inited==0) return; + va_list args; + size_t length; + static char log_buf[CONSOLEBUF_SIZE]; + static const char *level_str[]={"[info] ","[log] ","[warn] ","[err] "}; + static int level_str_len[]={7,6,7,6}; + if(levelDBG_LEVEL_ERR) return; + #ifdef RT_THREAD + rt_mutex_take(&self->mutex,RT_WAITING_FOREVER); + #endif + #ifdef LINUX + _sem_take(self->mutex); + #endif + memcpy(log_buf,level_str[level],level_str_len[level]); + length=level_str_len[level]; + length+=sprintf(log_buf + length,"%s|%s|%d| ",file,fun,line); + + va_start(args, fmt); + length += vsnprintf(log_buf + length, CONSOLEBUF_SIZE - length - 3, fmt, args); + va_end(args); + if (length > CONSOLEBUF_SIZE - 3) + length = CONSOLEBUF_SIZE - 3; + if(log_buf[length-1]!='\n'){ + memcpy(&log_buf[length],"\n",1); + length+=1; + } + log_buf[length]=0; + self->dev->write((const uint8_t *)log_buf,length); + #ifdef RT_THREAD + rt_mutex_release(&self->mutex); + #endif + #ifdef LINUX + _sem_relase(self->mutex); + #endif +} + + diff --git a/soft/debug.h b/soft/debug.h new file mode 100644 index 0000000..61dfb11 --- /dev/null +++ b/soft/debug.h @@ -0,0 +1,68 @@ +#ifndef debug_h__ +#define debug_h__ + + +#include "stdint.h" +#include "stdio.h" + + + + +/*r{ 淇敼鏃ュ織鎵撳嵃绛夌骇 }c*/ +#define DBG_LOG_LEVEL DBG_LEVEL_INFO + + + +/*r{ 瀹氫箟鎵撳嵃鏁版嵁绛夌骇 }c*/ +#define DBG_LEVEL_INFO 0 +#define DBG_LEVEL_LOG 1 +#define DBG_LEVEL_WARN 2 +#define DBG_LEVEL_ERR 3 + + +#if (DBG_LOG_LEVEL<=DBG_LEVEL_INFO) +#define DBG_INFO( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_INFO, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_INFO( ml_msg_, ...) +#endif +#if (DBG_LOG_LEVEL<=DBG_LEVEL_LOG) +#define DBG_LOG( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_LOG, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_LOG( ml_msg_, ...) +#endif +#if (DBG_LOG_LEVEL<=DBG_LEVEL_WARN) +#define DBG_WARN( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_WARN, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_WARN( ml_msg_, ...) +#endif +#if (DBG_LOG_LEVEL<=DBG_LEVEL_ERR) +#define DBG_ERR( ml_msg_, ...) \ + DBG_LOG_(DBG_LEVEL_ERR, (ml_msg_), ##__VA_ARGS__) +#else +#define DBG_ERR( ml_msg_, ...) +#endif + + +#define DBG_LOG_(type_,msg_,...)\ + debug_log(__FILE__,__func__,__LINE__,type_,(msg_),##__VA_ARGS__) + + + +typedef struct{ + int (*init)(); + int (*write)(const uint8_t *data,size_t len); +}dbg_dev; + + + + +int debug_init(dbg_dev *dev); + +void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...); + + +#endif + diff --git a/soft/exception.c b/soft/exception.c index c78b7ea..93ea06a 100644 --- a/soft/exception.c +++ b/soft/exception.c @@ -8,12 +8,15 @@ #include "stdarg.h" #include "exception.h" #include "mystdlib.h" +#include "debug.h" +#include "mythread.h" exception_def *exception(){ - static exception_def frame={0}; - return &frame; + exception_def *frame; + frame=&myth_self()->except; + return frame; } @@ -54,31 +57,30 @@ void func_two(); int test_add(int a, int b) { - printf("setjmp test.\n"); + DBG_INFO("setjmp test.\n"); try_{ - printf("first enter setjmp.\n"); + DBG_INFO("first enter setjmp.\n"); try_{ - printf("try in try.\n"); + DBG_INFO("try in try.\n"); func_two(); // throw_("throw two err."); }catch_{ - printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_()); + DBG_WARN("file=%s,line=%d,err=%s.\n",file_(),line_(),err_()); } throw_("throw a err."); }catch_{ - printf("sssss\n"); - printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_()); + DBG_WARN("file=%s,line=%d,err=%s.\n",file_(),line_(),err_()); try_{ - printf("try in catch.\n"); + DBG_INFO("try in catch.\n"); func_two(); // throw_("throw two err."); }catch_{ - printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_()); + DBG_WARN("file=%s,line=%d,err=%s.\n",file_(),line_(),err_()); } } - printf("setjmp end.\n"); + DBG_INFO("setjmp end.\n"); return 0; } @@ -87,7 +89,7 @@ int test_add(int a, int b) void func_two(){ - printf("in func:%s\n",__func__); + DBG_INFO("in func:%s\n",__func__); void *p=mem_malloc(512); throw_("throw in func_two. in func:%s",__func__); mem_free(p); diff --git a/soft/mystdlib.c b/soft/mystdlib.c index 00d687f..401617f 100644 --- a/soft/mystdlib.c +++ b/soft/mystdlib.c @@ -3,6 +3,7 @@ #include "string.h" #include "exception.h" #include "stdio.h" +#include "debug.h" static void __mem_append_m(map_def **m,void *p); @@ -17,7 +18,7 @@ void __mem_clear(map_def **m){ for(size_t i=0;imap_size;i++){ if((*m)->mem_map[i]==(size_t)p){ (*m)->mem_map[i]=0; - printf("free eme_p=%08lx\n",(size_t)p); + DBG_INFO("free eme_p=%08lx\n",(size_t)p); (*m)->mam_used--; break; } @@ -77,7 +78,7 @@ static void __mem_append_m(map_def **m,void *p){ for(size_t i=0;i<(*m)->map_size;i++){ if((*m)->mem_map[i]==0){ (*m)->mem_map[i]=(size_t)p; - printf("append eme_p=%08lx\n",(size_t)p); + DBG_INFO("append eme_p=%08lx\n",(size_t)p); (*m)->mam_used++; break; } diff --git a/soft/mythread.c b/soft/mythread.c index 05ab92a..c97534c 100644 --- a/soft/mythread.c +++ b/soft/mythread.c @@ -5,17 +5,9 @@ #include "mythread.h" #include "exception.h" #include "stdio.h" +#include "debug.h" -typedef struct _myth_def{ - struct _myth_def *next; - struct _myth_def *last; - pthread_t th; - exception_def except; - size_t id; - int (*func)(void *); - void *arg; -}myth_def; typedef struct{ myth_def *head; @@ -32,17 +24,18 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, static void *p_thread(void *t){ myth_def *th=(myth_def *)t; th->id=(size_t)pthread_self(); - printf("func:%08lx start id=%d.\n",(size_t)th->func,th->id); + DBG_INFO("func:%08lx start id=%d.\n",(size_t)th->func,th->id); try_{ if(!th->func){ throw_("th->func was null."); } th->func(th->arg); }catch_{ - printf("func:%08lx failed.\n",(size_t)th->func); - printf("file=%s,line=%d,err=%s\n",exception()->file,exception()->line,exception()->log); + DBG_WARN("func:%08lx failed.\n",(size_t)th->func); + DBG_WARN("file=%s,line=%d,err=%s\n",exception()->file,exception()->line,exception()->log); } - printf("func:%08lx end.\n",(size_t)th->func); + DBG_INFO("func:%08lx end.\n",(size_t)th->func); + th->end=1; return 0; } @@ -85,3 +78,20 @@ int myth_join(){ return 0; } + + +myth_def *myth_self(){ + self_def *s=&g_self; + myth_def *myth=s->head; + size_t id=(size_t)pthread_self(); + while(myth){ + if(myth->id==id){ + return myth; + } + myth=myth->next; + } + printf("can not find myth.\n"); + return NULL; +} + + diff --git a/soft/mythread.h b/soft/mythread.h index 337f472..d9954dd 100644 --- a/soft/mythread.h +++ b/soft/mythread.h @@ -3,10 +3,27 @@ #include "pthread.h" +#include "exception.h" + + +typedef struct _myth_def{ + struct _myth_def *next; + struct _myth_def *last; + pthread_t th; + exception_def except; + size_t id; + size_t end; + int (*func)(void *); + void *arg; +}myth_def; + + + + int myth_create(int (*func)(void *t),void *t); int myth_join(); - +myth_def *myth_self(); #endif