linuxcan编程
Ⅰ linux系统下can怎么通信的
struct can_frame rx,tx;
tx.can_id = 0x00000008;
tx.can_dlc = 8;
tx.data[0] = 0xA1;
tx.data[1] = 0xF0;
tx.data[2] = 0x00;
tx.data[3] = 0x51;
tx.data[4] = 0x02;
tx.data[5] = 0x03;
tx.data[6] = 0x04;
tx.data[7] = tx.data[0] + tx.data[1] + tx.data[2] + tx.data[3] + tx.data[4] + tx.data[5] + tx.data[6];
int m = write(can_fd, &tx, sizeof(struct can_frame));
printf("can send...............%d\n",m);
那么牛的程序,不像是学校的考试题。 
起码是linux 下的C语言编程,搞嵌入式开发的吧。 
我也来试试,正想向这个方向研究呢。呵呵 
另:公司只能上网络,只能这里给你了. 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#define LEN 100 
main() 
{ 
int fd, len; 
int i; 
char ch[LEN]; 
fd=open("test.txt",O_CREAT|O_RDWR,10705); 
if(fd) 
{ 
for(i=1;i<101;i++) 
{ 
sprintf(ch,"%d",i); 
write(fd,ch,strlen(ch)); 
} 
close(fd); 
} 
fd = open("test.txt",O_RDWR); 
lseek(fd,50,SEEK_SET); 
if(fd) 
{ 
len = read(fd,ch,1); 
ch[len] = '\0'; 
printf("%s\n",ch); 
} 
lseek(fd,100,SEEK_SET); 
if(fd) 
{ 
len = read(fd,ch,1); 
ch[len] = '\0'; 
printf("%s\n",ch); 
} 
close(fd); 
if(!remove("test.txt")) 
printf("test.txt have remove\n"); 
else 
printf("can't remove\n"); 
} 
这是第一题.
Ⅲ Linux下C编程,实现每3秒输出一次时间,并且保存在文件中,程序运行有错误
结构体的大小不能简单认为就是成员的叠加..!!!
所以你fprintf(“%d”)并不是说数据存文本里面就占四个字节,只是用10进制打印出来,可能是1个字节,也可能是5个字节,你fprintf("%s"),虽然长度在实际上就是24+1个字节,但是结构体中组织数据是需要对齐的.. temp2[25]占用内存是28个字节,因为是32位机,数据一般会四个字节对齐...对一个字节也是这样..自己看看sizeof(struct shijian)的大小....
fprintf("%4d")
fprintf("%28s")
用格式输出保证这个10进制数字的字符串占4个字节,这个时间的字符串占28个字节
这样就把文本的数据组织的和结构体一样大了..
调试的时候看看到底读出了多少个字节...fread你可以把单元设置为1,这样就能自己看读出出多少个字节,fread给你算了你当然看不到细节...
#include<stdio.h>
#include<time.h>
#include<string.h>
int main(int argc,char *argv[])
{
 time_t timep1;
 struct shijian
 {
 int number;
  char timep2[25];
 };
 FILE *fp=NULL;
 if ((fp=fopen("1.txt","a+"))==NULL)
 {
  printf("can not open !");
  return -1;
 }
 struct shijian shijian[200];
 int i=1;
 int rc;
 while(i==1 && rc < 10000)//rc超出10000的话,程序就又会不对劲了...只给了4个位
 {
 rc=fread(shijian,sizeof(struct shijian),200,fp);
 // fflush(fp);
 shijian->number=rc+1;
//   shijian->number=i;
//   i=rc;
  time(&timep1);
  strcpy(shijian->timep2,ctime(&timep1));
  printf("%d  %s\n",shijian->number,shijian->timep2);
 // fwrite(q->number,sizeof(q->number),1,fp);
 // fflush(fp);
fprintf(fp,"%4d",shijian->number);fflush(fp);
  fprintf(fp,"%28s",shijian->timep2);fflush(fp);
 // fwrite(shijian->timep2,sizeof(shijian->timep2),1,fp);
  rewind(fp);
  
  sleep(3);
 // fseek(fp,0,SEEK_SET);
 // (shijian->number)++;
 }
 fclose(fp);
 return 0;
}
Ⅳ 如何看懂《Linux多线程服务端编程
一:进程和线程
每个进程有自己独立的地址空间。“在同一个进程”还是“不在同一个进程”是系统功能划分的重要决策点。《Erlang程序设计》[ERL]把进程比喻为人:
每个人有自己的记忆(内存),人与人通过谈话(消息传递)来交流,谈话既可以是面谈(同一台服务器),也可以在电话里谈(不同的服务器,有网络通信)。面谈和电话谈的区别在于,面谈可以立即知道对方是否死了(crash,SIGCHLD),而电话谈只能通过周期性的心跳来判断对方是否还活着。
有了这些比喻,设计分布式系统时可以采取“角色扮演”,团队里的几个人各自扮演一个进程,人的角色由进程的代码决定(管登录的、管消息分发的、管买卖的等等)。每个人有自己的记忆,但不知道别人的记忆,要想知道别人的看法,只能通过交谈(暂不考虑共享内存这种IPC)。然后就可以思考:
·容错:万一有人突然死了
·扩容:新人中途加进来
·负载均衡:把甲的活儿挪给乙做
·退休:甲要修复bug,先别派新任务,等他做完手上的事情就把他重启
等等各种场景,十分便利。
线程的特点是共享地址空间,从而可以高效地共享数据。一台机器上的多个进程能高效地共享代码段(操作系统可以映射为同样的物理内存),但不能共享数据。如果多个进程大量共享内存,等于是把多进程程序当成多线程来写,掩耳盗铃。
“多线程”的价值,我认为是为了更好地发挥多核处理器(multi-cores)的效能。在单核时代,多线程没有多大价值(个人想法:如果要完成的任务是CPU密集型的,那多线程没有优势,甚至因为线程切换的开销,多线程反而更慢;如果要完成的任务既有CPU计算,又有磁盘或网络IO,则使用多线程的好处是,当某个线程因为IO而阻塞时,OS可以调度其他线程执行,虽然效率确实要比任务的顺序执行效率要高,然而,这种类型的任务,可以通过单线程的”non-blocking IO+IO multiplexing”的模型(事件驱动)来提高效率,采用多线程的方式,带来的可能仅仅是编程上的简单而已)。Alan Cox说过:”A computer is a state machine.Threads are for people who can’t program state machines.”(计算机是一台状态机。线程是给那些不能编写状态机程序的人准备的)如果只有一块CPU、一个执行单元,那么确实如Alan Cox所说,按状态机的思路去写程序是最高效的。
二:单线程服务器的常用编程模型
据我了解,在高性能的网络程序中,使用得最为广泛的恐怕要数”non-blocking IO + IO multiplexing”这种模型,即Reactor模式。
在”non-blocking IO + IO multiplexing”这种模型中,程序的基本结构是一个事件循环(event loop),以事件驱动(event-driven)和事件回调的方式实现业务逻辑:
[cpp] view plain  
//代码仅为示意,没有完整考虑各种情况  
while(!done)  
{  
int timeout_ms = max(1000, getNextTimedCallback());  
int retval = poll(fds, nfds, timeout_ms);  
if (retval<0){  
处理错误,回调用户的error handler  
}else{  
处理到期的timers,回调用户的timer handler  
if(retval>0){  
处理IO事件,回调用户的IO event handler  
}  
}  
}  
这里select(2)/poll(2)有伸缩性方面的不足(描述符过多时,效率较低),Linux下可替换为epoll(4),其他操作系统也有对应的高性能替代品。
Reactor模型的优点很明显,编程不难,效率也不错。不仅可以用于读写socket,连接的建立(connect(2)/accept(2)),甚至DNS解析都可以用非阻塞方式进行,以提高并发度和吞吐量(throughput),对于IO密集的应用是个不错的选择。lighttpd就是这样,它内部的fdevent结构十分精妙,值得学习。
基于事件驱动的编程模型也有其本质的缺点,它要求事件回调函数必须是非阻塞的。对于涉及网络IO的请求响应式协议,它容易割裂业务逻辑,使其散布于多个回调函数之中,相对不容易理解和维护。
三:多线程服务器的常用编程模型
大概有这么几种:
a:每个请求创建一个线程,使用阻塞式IO操作。在Java 1.4引人NIO之前,这是Java网络编程的推荐做法。可惜伸缩性不佳(请求太多时,操作系统创建不了这许多线程)。
b:使用线程池,同样使用阻塞式IO操作。与第1种相比,这是提高性能的措施。
c:使用non-blocking IO + IO multiplexing。即Java NIO的方式。
d:Leader/Follower等高级模式。
在默认情况下,我会使用第3种,即non-blocking IO + one loop per thread模式来编写多线程C++网络服务程序。
1:one loop per thread
此种模型下,程序里的每个IO线程有一个event  loop,用于处理读写和定时事件(无论周期性的还是单次的)。代码框架跟“单线程服务器的常用编程模型”一节中的一样。
libev的作者说:
One loop per thread is usually a good model. Doing this is almost never wrong, some times a better-performance model exists, but it is always a good start.
这种方式的好处是:
a:线程数目基本固定,可以在程序启动的时候设置,不会频繁创建与销毁。
b:可以很方便地在线程间调配负载。
c:IO事件发生的线程是固定的,同一个TCP连接不必考虑事件并发。
Event loop代表了线程的主循环,需要让哪个线程干活,就把timer或IO channel(如TCP连接)注册到哪个线程的loop里即可:对实时性有要求的connection可以单独用一个线程;数据量大的connection可以独占一个线程,并把数据处理任务分摊到另几个计算线程中(用线程池);其他次要的辅助性connections可以共享一个线程。
比如,在dbproxy中,一个线程用于专门处理客户端发来的管理命令;一个线程用于处理客户端发来的MySQL命令,而与后端数据库通信执行该命令时,是将该任务分配给所有事件线程处理的。
对于non-trivial(有一定规模)的服务端程序,一般会采用non-blocking IO + IO multiplexing,每个connection/acceptor都会注册到某个event loop上,程序里有多个event loop,每个线程至多有一个event loop。
多线程程序对event loop提出了更高的要求,那就是“线程安全”。要允许一个线程往别的线程的loop里塞东西,这个loop必须得是线程安全的。
在dbproxy中,线程向其他线程分发任务,是通过管道和队列实现的。比如主线程accept到连接后,将表示该连接的结构放入队列,并向管道中写入一个字节。计算线程在自己的event loop中注册管道的读事件,一旦有数据可读,就尝试从队列中取任务。
2:线程池
不过,对于没有IO而光有计算任务的线程,使用event loop有点浪费。可以使用一种补充方案,即用blocking  queue实现的任务队列:
[cpp] view plain  
typedef boost::function<void()>Functor;  
BlockingQueue<Functor> taskQueue;   //线程安全的全局阻塞队列  
//计算线程  
void workerThread()  
{  
while (running) //running变量是个全局标志  
{  
Functor task = taskQueue.take();    //this blocks  
task();     //在产品代码中需要考虑异常处理  
}  
}  
// 创建容量(并发数)为N的线程池  
int N = num_of_computing_threads;  
for (int i = 0; i < N; ++i)  
{  
create_thread(&workerThread);   //启动线程  
}  
//向任务队列中追加任务  
Foo foo;    //Foo有calc()成员函数  
boost::function<void()> task = boost::bind(&Foo::calc,&foo);  
taskQueue.post(task);  
除了任务队列,还可以用BlockingQueue<T>实现数据的生产者消费者队列,即T是数据类型而非函数对象,queue的消费者从中拿到数据进行处理。其实本质上是一样的。
3:总结
总结而言,我推荐的C++多线程服务端编程模式为:one (event) loop per thread + thread pool:
event  loop用作IO multiplexing,配合non-blockingIO和定时器;
thread  pool用来做计算,具体可以是任务队列或生产者消费者队列。
以这种方式写服务器程序,需要一个优质的基于Reactor模式的网络库来支撑,muo正是这样的网络库。比如dbproxy使用的是libevent。
程序里具体用几个loop、线程池的大小等参数需要根据应用来设定,基本的原则是“阻抗匹配”(解释见下),使得CPU和IO都能高效地运作。所谓阻抗匹配原则:
如果池中线程在执行任务时,密集计算所占的时间比重为 P (0 < P <= 1),而系统一共有 C 个 CPU,为了让这 C 个 CPU 跑满而又不过载,线程池大小的经验公式 T = C/P。(T 是个 hint,考虑到 P 值的估计不是很准确,T 的最佳值可以上下浮动 50%)
以后我再讲这个经验公式是怎么来的,先验证边界条件的正确性。
假设 C = 8,P = 1.0,线程池的任务完全是密集计算,那么T = 8。只要 8 个活动线程就能让 8 个 CPU 饱和,再多也没用,因为 CPU 资源已经耗光了。
假设 C = 8,P = 0.5,线程池的任务有一半是计算,有一半等在 IO 上,那么T = 16。考虑操作系统能灵活合理地调度 sleeping/writing/running 线程,那么大概 16 个“50%繁忙的线程”能让 8 个 CPU 忙个不停。启动更多的线程并不能提高吞吐量,反而因为增加上下文切换的开销而降低性能。
如果 P < 0.2,这个公式就不适用了,T 可以取一个固定值,比如 5*C。
另外,公式里的 C 不一定是 CPU 总数,可以是“分配给这项任务的 CPU 数目”,比如在 8 核机器上分出 4 个核来做一项任务,那么 C=4。
四:进程间通信只用TCP
Linux下进程间通信的方式有:匿名管道(pipe)、具名管道(FIFO)、POSIX消息队列、共享内存、信号(signals),以及Socket。同步原语有互斥器(mutex)、条件变量(condition variable)、读写锁(reader-writer lock)、文件锁(record locking)、信号量(semaphore)等等。
进程间通信我首选Sockets(主要指TCP,我没有用过UDP,也不考虑Unix domain协议)。其好处在于:
可以跨主机,具有伸缩性。反正都是多进程了,如果一台机器的处理能力不够,很自然地就能用多台机器来处理。把进程分散到同一局域网的多台机器上,程序改改host:port配置就能继续用;
TCP sockets和pipe都是操作文件描述符,用来收发字节流,都可以read/write/fcntl/select/poll等。不同的是,TCP是双向的,Linux的pipe是单向的,进程间双向通信还得开两个文件描述符,不方便;而且进程要有父子关系才能用pipe,这些都限制了pipe的使用;
TCP port由一个进程独占,且进程退出时操作系统会自动回收文件描述符。因此即使程序意外退出,也不会给系统留下垃圾,程序重启之后能比较容易地恢复,而不需要重启操作系统(用跨进程的mutex就有这个风险);而且,port是独占的,可以防止程序重复启动,后面那个进程抢不到port,自然就没法初始化了,避免造成意料之外的结果;
与其他IPC相比,TCP协议的一个天生的好处是“可记录、可重现”。tcpmp和Wireshark是解决两个进程间协议和状态争端的好帮手,也是性能(吞吐量、延迟)分析的利器。我们可以借此编写分布式程序的自动化回归测试。也可以用tcp之类的工具进行压力测试。TCP还能跨语言,服务端和客户端不必使用同一种语言。
分布式系统的软件设计和功能划分一般应该以“进程”为单位。从宏观上看,一个分布式系统是由运行在多台机器上的多个进程组成的,进程之间采用TCP长连接通信。
使用TCP长连接的好处有两点:一是容易定位分布式系统中的服务之间的依赖关系。只要在机器上运行netstat  -tpna|grep  <port>就能立刻列出用到某服务的客户端地址(Foreign Address列),然后在客户端的机器上用netstat或lsof命令找出是哪个进程发起的连接。TCP短连接和UDP则不具备这一特性。二是通过接收和发送队列的长度也较容易定位网络或程序故障。在正常运行的时候,netstat打印的Recv-Q和Send-Q都应该接近0,或者在0附近摆动。如果Recv-Q保持不变或持续增加,则通常意味着服务进程的处理速度变慢,可能发生了死锁或阻塞。如果Send-Q保持不变或持续增加,有可能是对方服务器太忙、来不及处理,也有可能是网络中间某个路由器或交换机故障造成丢包,甚至对方服务器掉线,这些因素都可能表现为数据发送不出去。通过持续监控Recv-Q和Send-Q就能及早预警性能或可用性故障。以下是服务端线程阻塞造成Recv-Q和客户端Send-Q激增的例子:
[cpp] view plain  
$netstat -tn  
Proto  Recv-Q  Send-Q  Local Address    Foreign  
tcp     78393       0  10.0.0.10:2000   10.0.0.10:39748     #服务端连接  
tcp         0  132608  10.0.0.10:39748  10.0.0.10:2000      #客户端连接  
tcp         0      52  10.0.0.10:22     10.0.0.4:55572  
五:多线程服务器的适用场合
如果要在一台多核机器上提供一种服务或执行一个任务,可用的模式有:
a:运行一个单线程的进程;
b:运行一个多线程的进程;
c:运行多个单线程的进程;
d:运行多个多线程的进程;
考虑这样的场景:如果使用速率为50MB/s的数据压缩库,进程创建销毁的开销是800微秒,线程创建销毁的开销是50微秒。如何执行压缩任务?
如果要偶尔压缩1GB的文本文件,预计运行时间是20s,那么起一个进程去做是合理的,因为进程启动和销毁的开销远远小于实际任务的耗时。
如果要经常压缩500kB的文本数据,预计运行时间是10ms,那么每次都起进程      似乎有点浪费了,可以每次单独起一个线程去做。
如果要频繁压缩10kB的文本数据,预计运行时间是200微秒,那么每次起线程似      乎也很浪费,不如直接在当前线程搞定。也可以用一个线程池,每次把压缩任务交给线程池,避免阻塞当前线程(特别要避免阻塞IO线程)。
由此可见,多线程并不是万灵丹(silver bullet)。
1:必须使用单线程的场合
据我所知,有两种场合必须使用单线程:
a:程序可能会fork(2);
实际编程中,应该保证只有单线程程序能进行fork(2)。多线程程序不是不能调用fork(2),而是这么做会遇到很多麻烦:
fork一般不能在多线程程序中调用,因为Linux的fork只克隆当前线程的thread of control,不可隆其他线程。fork之后,除了当前线程之外,其他线程都消失了。
这就造成一种危险的局面。其他线程可能正好处于临界区之内,持有了某个锁,而它突然死亡,再也没有机会去解锁了。此时如果子进程试图再对同一个mutex加锁,就会立即死锁。因此,fork之后,子进程就相当于处于signal handler之中(因为不知道调用fork时,父进程中的线程此时正在调用什么函数,这和信号发生时的场景一样),你不能调用线程安全的函数(除非它是可重入的),而只能调用异步信号安全的函数。比如,fork之后,子进程不能调用:
malloc,因为malloc在访问全局状态时几乎肯定会加锁;
任何可能分配或释放内存的函数,比如snprintf;
任何Pthreads函数;
printf系列函数,因为其他线程可能恰好持有stdout/stderr的锁;
除了man 7 signal中明确列出的信号安全函数之外的任何函数。
因此,多线程中调用fork,唯一安全的做法是fork之后,立即调用exec执行另一个程序,彻底隔断子进程与父进程的联系。
在多线程环境中调用fork,产生子进程后。子进程内部只存在一个线程,也就是父进程中调用fork的线程的副本。
使用fork创建子进程时,子进程通过继承整个地址空间的副本,也从父进程那里继承了所有互斥量、读写锁和条件变量的状态。如果父进程中的某个线程占有锁,则子进程同样占有这些锁。问题是子进程并不包含占有锁的线程的副本,所以子进程没有办法知道它占有了哪些锁,并且需要释放哪些锁。
尽管Pthread提供了pthread_atfork函数试图绕过这样的问题,但是这回使得代码变得混乱。因此《Programming With Posix Threads》一书的作者说:”Avoid using fork in threaded code except where the child process will immediately exec a new program.”。
b:限制程序的CPU占用率;
这个很容易理解,比如在一个8核的服务器上,一个单线程程序即便发生busy-wait,占满1个core,其CPU使用率也只有12.5%,在这种最坏的情况下,系统还是有87.5%的计算资源可供其他服务进程使用。
因此对于一些辅助性的程序,如果它必须和主要服务进程运行在同一台机器的话,那么做成单线程的能避免过分抢夺系统的计算资源。
Ⅳ linux can 怎么设置波特率
CAN位时间特性寄存器 (CAN_BTR)
地址偏移量: 0x1C
复位值: 0x0123 0000
注: 当CAN处于初始化模式时,该寄存器只能由软件访问。
                                                                                         图2
位31    SILM: 静默模式(用于调试)
0: 正常状态;
1: 静默模式。    
位30    LBKM: 环回模式(用于调试)
0: 禁止环回模式;
1: 允许环回模式。    
位29:26    保留位,硬件强制为0。    
位25:24    SJW[1:0]: 重新同步跳跃宽度
为了重新同步,该位域定义了CAN硬件在每位中可以延长或缩短多少个时间单元的上限。
tRJW = tCAN x (SJW[1:0] + 1)。    
位23    保留位,硬件强制为0。    
位22:20    TS2[2:0]: 时间段2
该位域定义了时间段2占用了多少个时间单元
tBS2 = tCAN x (TS2[2:0] + 1)。    
位19:16    TS1[3:0]: 时间段1
该位域定义了时间段1占用了多少个时间单元
tBS1 = tCAN x (TS1[3:0] + 1)    
位15:10    保留位,硬件强制其值为0。    
位9:0    BRP[9:0]: 波特率分频器
该位域定义了时间单元(tq)的时间长度
tq = (BRP[9:0]+1) x tPCLK    
3 如何在代码中配置波特率
配置波特率是在CAN模块初始化时配置,代码示例如下:
//CAN1 register init 
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
	
//CAN cell init 
CAN_InitStructure.CAN_TTCM = DISABLE; 
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE; 
CAN_InitStructure.CAN_NART = DISABLE; 
CAN_InitStructure.CAN_RFLM = DISABLE; 
CAN_InitStructure.CAN_TXFP = ENABLE; 
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; 
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; 
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq; //tBS1=6个tCAN时钟周期
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; //tBS2=8个tCAN时钟周期
CAN_InitStructure.CAN_Prescaler = 4; //ABP总线时钟时钟4分频
	
//CANbps= Fpclk/((BRP+1)*((Tseg1+1)+(Tseg2+1)+1)  
//所以这里CANbps=30000000/4/(8+6+1))=500k bps
//总体配置方向: Tseg1>=Tseg2  Tseg2>=tq; Tseg2>=2TSJW	
if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED) 		
{
       return _ERROR;									                  
}
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);//打开FMP0中断
总体配置保持tBS1>=tBS2 tBS2>=1个CAN时钟周期  tBS2>=2tSJW
Ⅵ linux下c语言编程
实在点,给你些命令操作操作,不过好象有点多,哈哈
Linux/Unix常用命令
1、目录操作
和DOS相似,UNIX采用树型目录管理结构,由根目录(/)开始一层层将子目录建下去,各子目录以 / 隔开。用户login后,工作目录的位置称为  home   directory,由系统管理员设定。‘~’符号代表自己的home   directory,例如  ~/myfile 是指自己home目录下myfile这个文件。
(1)显示目录文件    ls
执行格式:  ls  [-atFlgR] [name]       (name可为文件或目录名称)
例:  ls             显示出当前目录下的文件
ls  -a        显示出包含隐藏文件的所有文件
ls  -t         按照文件最后修改时间显示文件  
ls  -F         显示出当前目录下的文件及其类型
ls  -l         显示目录下所有文件的许可权、拥有者、文件大小、修改时间及名称
ls  -lg        同上
ls  -R         显示出该目录及其子目录下的文件 
   注:ls与其它命令搭配使用可以生出很多技巧(最简单的如"ls -l | more"),更多用法请输入ls --help查看,其它命令的更多用法请输入   命令名 --help  查看.
(2)建新目录   mkdir
执行格式:      mkdir   directory-name
例:            mkdir   dir1   (新建一名为dir1的目录)
(3)删除目录  rmdir
执行格式:      rmdir    directory-name  或  rm   directory-name
例:rmdir  dir1      删除目录dir1,但它必须是空目录,否则无法删除
     rm  -r  dir1     删除目录dir1及其下所有文件及子目录
     rm  -rf dir1    不管是否空目录,统统删除,而且不给出提示,使用时要小心
(4) 改变工作目录位置     cd
执行格式:    cd  [name]                       
例: cd            改变目录位置至用户login时的working  directory
     cd  dir1       改变目录位置,至dir1目录
     cd  ~user      改变目录位置,至用户的working directory
     cd  ..         改变目录位置,至当前目录的上层目录
     cd  ../user    改变目录位置,至上一级目录下的user目录
     cd  /dir-name1/dir-name2       改变目录位置,至绝对路径(Full  path)
     cd  -          回到进入当前目录前的上一个目录
(5)显示当前所在目录pwd
执行格式:           pwd
(6)查看目录大小
执行格式:       [-s]  directory
例:      dir1         显示目录dir1及其子目录容量(以kb为单位)
         -s  dir1      显示目录dir1的总容量
    (7)显示环境变量
     echo $HOME    显示家目录
     echo $PATH    显示可执行文件搜索路径
     env           显示所有环境变量(可能很多,最好用"env | more","env |                  grep PATH"等)
(8)修改环境变量,在bash下用export,如:
     export PATH=$PATH:/usr/local/bin
     想知道export的具体用法,可以用shell的help命令:help export
2、文件操作
(1)查看文件(可以是二进制的)内容  cat
执行格式:cat filename或more filename 或cat filename|more
例:      cat file1       以连续显示方式,查看文件file1的内容
more  file1     
或    cat  file1|more 以分页方式查看文件的内容
(2)删除文件  rm
执行格式:  rm   filename     
例:        rm     file?              
rm    f*         
(3)复制文件  cp
   执行格式:    cp  [-r]  source  destination 
例:    cp   file1  file2       将file1复制成file2
        cp   file1  dir1        将file1复制到目录dir1
        cp  /tmp/file1          将file1复制到当前目录
        cp  /tmp/file1  file2    将file1 复制到当前目录名为file2
cp  -r  dir1  dir2      (recursive  )复制整个目录。                        
(4)移动或更改文件、目录名称mv
执行格式:       mv  source  destination
例:    mv  file1  file2       将文件file1,更名为file2
        mv  file1  dir1        将文件file1,移到目录dir1下
mv  dir1   dir2        
(5)比较文件(可以是二进制的)或目录的内容   diff
  执行格式: diff [-r] name1 name2   (name1、name2同为文件或目录)
         例:   diff  file1  file2        比较file1与file2的不同处 
diff   -r  dir1  dir2     比较dir1与dir2的不同处
(6)文件中字符串的查找       grep
执行格式:     grep   string  file
例:      grep  abc  file1      查找并列出串abc所在的整行文字
(7)文件或命令的路径寻找
执行格式一:whereis  command  显示命令的路径
执行格式二:which  command   显示路径及使用者所定义的别名
执行格式三:whatis   command  显示命令的功能摘要
(8)建立文件或目录的链接   ln
例:    ln    source  target1  建立source文件(已存在)的硬链接,命名为target1
       ln -s  source  target2   建立source文件的符号链接,命名为target2
文件编辑器vi 
vi是在UNIX 上被广泛使用的中英文编辑软件。vi是visual  editor的缩写,是UNIX提供给用户的一个窗口化编辑环境。
进入vi,直接执行vi编辑程序即可。
例:$vi  test.c
显示器出现vi的编辑窗口,同时vi会将文件复制一份至缓冲区(buffer)。vi先对缓冲区的文件进行编辑,保留在磁盘中的文件则不变。编辑完成后,使用者可决定是否要取代原来旧有的文件。
1、vi的工作模式
vi提供二种工作模式:输入模式(insert  mode)和命令模式(command  mode)。使用者进入vi后,即处在命令模式下,此刻键入的任何字符皆被视为命令,可进行删除、修改、存盘等操作。要输入信息,应转换到输入模式。
(1)命令模式
在输入模式下,按ESC可切换到命令模式。命令模式下,可选用下列指令离开vi:
:q! 离开vi,并放弃刚在缓冲区内编辑的内容 
:wq 将缓冲区内的资料写入磁盘中,并离开vi 
:ZZ 同wq 
:x 同wq 
:w 将缓冲区内的资料写入磁盘中,但并不离开vi 
:q 离开vi,若文件被修改过,则要被要求确认是否放弃修改的内容,此指令可与:w配合使用 
(2)命令模式下光标的移动 
H 左移一个字符 
J 下移一个字符 
K 上移一个字符 
L 右移一个字符 
0 移至该行的首 
$ 移至该行的末 
^ 移至该行的第一个字符处 
H 移至窗口的第一列 
M 移至窗口中间那一列 
L 移至窗口的最后一列 
G 移至该文件的最后一列 
W, W 下一个单词 (W 忽略标点) 
B, B  上一个单词 (B 忽略标点) 
+ 移至下一列的第一个字符处 
- 移至上一列的第一个字符处 
( 移至该句首 
) 移至该句末 
{ 移至该段首 
} 移至该段末 
NG 移至该文件的第n列 
N+ 移至光标所在位置之后第n列 
n- 移至光标所在位置之前第n列 
(3)输入模式
输入以下命令即可进入vi输入模式:
a(append)   在光标之后加入资料 
A   在该行之末加入资料 
i(insert) 在光标之前加入资料 
I   在该行之首加入资料 
o(open) 新增一行于该行之下,供输入资料用 
O 新增一行于该行之上,供输入资料用 
dd 删除当前光标所在行 
X 删除当前光标字符 
x 删除当前光标之前字符 
U 撤消 
• 重做 
F 查找 
 
ESC键 离开输入模式 
GNU C编译器
LINUX上可用的C编译器是GNU  C编译器,它建立在自由软件基金会编程许可证的基础上,因此可以自由发布。
LINUX 上的GNU  C编译器(GCC)是一个全功能的ANCI  C兼容编译器。下面介绍GCC和一些GCC编译器最常用的选项。
1、使用GCC
通常后跟一些选项和文件名来使用GCC编译器。GCC命令的基本用法如下:
      gcc [options] [filenames]
命令行选项指定的编译过程中的具体操作
2、GCC常用选项
GCC有超过100个的编译选项可用,这些选项中的许多可能永远都不会用到,但一些主要的选项将会频繁使用。很多的GCC选项包括一个以上的字符,因此必须为每个选项指定各自的连字符,并且就像大多数LINUX 命令一样不能在一个单独的连字符后跟一组选项。例如: 
gcc  test.c
编译成功后,当前目录下就产生了一个可执行文件a.out。
也可用-o选项来为即将产生的可执行文件指定一个文件名来代替a.out。例如:
gcc  -o  count  count.c
此时得到的可执行文件就不再是a.out,而是count。
3、执行文件   
格式:     ./可执行文件名
例:./a.out
    ./count
Ⅶ linux c编程
/* 
    Name: list.c 
    Author: guozan _SCS_BUPT 
    Mail: [email protected] 
    Date: 2010/4/6 
    实验目的:练习vi,使用UNIX的系统调用和库函数,体会UNIX文件通配符的处理方式以及命令对选项的处理方式。 
    编程实现程序list.c,列表普通磁盘文件(不考虑目录和设备文件等),列出文件名和文件大小。 
    与ls命令类似,命令行参数可以有0到多个 
    0个参数:列出当前目录下所有文件 
    参数为普通文件:列出文件 
    参数为目录:列出目录下所有文件 
    实现自定义选项r,a,l,h,m以及-- 
    r 递归方式列出子目录 
    a 列出文件名第一个字符为圆点的普通文件(默认情况下不列出文件名首字符为圆点的文件) 
    l 后跟一整数,限定文件大小的最小值(字节) 
    h 后跟一整数,限定文件大小的最大值(字节) 
    m 后跟一整数n,限定文件的最近修改时间必须在n天内 
    --  显式地终止命令选项分析 
*/  
#include <sys/stat.h>  
#include <sys/types.h>  
#include <dirent.h>  
#include <unistd.h>  
#include <stdio.h>  
#include <string.h>  
/* 
    slective options about ls 
    rflag is about recursive 
    aflag is about ones with . infront 
    lflag is about the minimum size 
    hflag is about the maximum size 
    mflag is about the modified time 
*/  
int rflag, aflag, lflag, hflag, mflag;  
long modified_time;        //the last time file be modified, days ago  
off_t lower_size;            //file's minimum size  
off_t upper_size;            //file's maximum size  
/* 
    set the flags, thus the ls option 
*/  
void getoptions(int argc, char *argv[])  
{  
    char ch;  
    //clear, all unseted  
    rflag = 0; aflag = 0; lflag = 0; hflag = 0; mflag = 0;  
    //use getopt to get the options, want to know more, call man  
    //the last one or after -- was set in argv[optind]  
    while ((ch = getopt(argc, argv, "ral:h:m:")) != -1) {  
        switch (ch) {  
            case 'r': rflag = 1; break;  
            case 'a': aflag = 1; break;  
            case 'l': lflag = 1; lower_size = atol(optarg); break;  
            case 'h': hflag = 1; upper_size = atol(optarg); break;  
            case 'm': mflag = 1; modified_time = atol(optarg); break;    //get days  
            case '?': printf("Unknown option: %c\n", (char)optopt); break;  
            default : printf("Step into default\n"); break;  
        }  
    }  
}  
/* 
    the function to list things in path 
*/  
int ls(char *path)  
{  
    struct stat st;        //for check this is a directory or file  
    char temp[100];        //if path is null, it is used to get current directory  
    // get the path  
    if (path == NULL || path[0] == '-') {  
        path = temp;  
        getcwd(path, 100);  
    }  
    /* open the inode of file */  
    if (lstat(path, &st)) {  
        fprintf(stderr, "Error: %s not exist.\n", path);  
        return (-1);  
    }  
    /* judge whether the file is a file or a directory */  
    if (S_ISDIR(st.st_mode)) {  
        ls_dir(path);  
    }  
    else if (S_ISREG(st.st_mode)) {  
        print(path);  
    }  
    else {  
        printf("Not ordinary file, wouldn't be listed.\n");  
    }  
    return 0;  
}  
/* 
    list dirs, may recursively or not, depending on rflag 
    one thing is sure that it will list directories and files first, 
    then consider the things in the directories 
*/  
int ls_dir(char *path)  
{  
    DIR *dp = NULL;  
    struct dirent *dirp = NULL;  
    if (path[0] != '.' || (path[0] == '.' && aflag == 1)) {  
        printf("\n%s:\n****************************************\n", path);  
        /* open the directory */  
        if ((dp = opendir(path)) == NULL) {  
            fprintf(stderr, "Error: can't open directory %s!\n", path);  
            return (-1);  
        }  
        chdir(path);  
        /* list all the things in directory */  
        while ((dirp = readdir(dp)) != NULL) {  
            print(dirp->d_name);  
        }  
        /* recursively ls dirs, after ls things together, 
            it's time to list things in children directory */  
        if (rflag == 1) {  
            rewinddir(dp);    //reset dp  
            while ((dirp = readdir(dp)) != NULL) {  
                if (strcmp(dirp->d_name, ".") == 0  
                    || strcmp(dirp->d_name, "..") == 0) {    //no current and parent directory  
                    continue;  
                }  
                ls_dir_r(dirp->d_name);        //only list directories, judged inside the function  
            }  
        }  
        /* close the directory */  
        if (closedir(dp)) {  
            fprintf(stderr, "Error: can't close the directory %s!\n", path);  
            return -1;  
        }  
        chdir("..");  
    }  
    return 0;  
}  
/* 
    list directories recursively, 
    only directories, nomatter what path you put in 
*/  
int ls_dir_r(char *path)  
{  
    struct stat st;  
    /* open the inode of file */  
    if (lstat(path, &st)) {  
        fprintf(stderr, "Error: %s not exist.\n", path);  
        return (-1);  
    }  
    /* only ls directories */  
    if (S_ISDIR(st.st_mode)) {  
        ls_dir(path);  
    }  
}  
/* 
    print the filetype/size/name on the screen 
*/  
int print(char *path)  
{  
    struct stat st;  
    time_t tp;  
    char *filename = NULL;  
    //get current time  
    time(&tp);  
    if (lstat(path, &st)) {  
        fprintf(stderr, "Error: %s can't be opened.\n", path);  
        return (-1);  
    }  
    /* get file name */  
    if ((filename = strrchr(path, '/')) != NULL) {  
        filename++;  
    }  
    else {  
        filename = path;  
    }  
    /* judge whether to list the file */  
    if ((S_ISDIR(st.st_mode)|| S_ISREG(st.st_mode))    //only directories and normal files  
        && (lflag == 0 || (lflag == 1 && (st.st_size >= lower_size)))         //the min size  
        && (hflag == 0 || (hflag == 1 && (st.st_size <= upper_size)))     //the max size  
        && (mflag == 0 || (mflag == 1 && ((tp - st.st_mtime) <= modified_time * 24 * 60 * 60)))    //modified time  
        && (aflag == 1 || (aflag == 0 && filename[0] != '.'))    //file with a '.' infront  
        ) {  
        printf("%s\t%10ld\t%s\n", (S_ISDIR(st.st_mode) ? "DIR": "FILE"), st.st_size, filename);  
    }  
    return 0;  
}  
/* 
    The main function 
*/  
int main(int argc, char *argv[])  
{  
    getoptions(argc, argv);  
    ls(argv[optind]);  
    return 0;  
}
Ⅷ linux内核中can总线怎么用的
会51吗?会C吗?如果不会的话就有点难度哦!会的话就学起来稍微轻松一点,只是轻松一点。学ARM肯定要先看汇编指令的,等指令看完了呢,就先看看别人写的汇编程序,能看懂就行了。然后了解ARM运行次序,首先不要过多的琢磨启动代码,只要理解启动代码是干些什么事就行,当然像有些ARM处理器是固化了启动代码的。先借用官方的或别人的启动代码用着,然后自己用C编写程序写些简单的程序像跑马灯啊、串口啊、I2C、SPI、AD、TFT、摄像头啊什么的,不过摄像头和TFT稍微难理解一点。先弄简单的,就当单片机一样用,这阶段主要是熟悉内部寄存器及其使用的。等资源懂了熟悉了,你再返过来看启动代码,那你就会豁然开朗。当然裸奔并不是ARM的精华部分,如果只是裸奔的话那么ARM就只能算个增强型单片机了,ARM的核心是操作系统的移植,及操作系统下应用程序、驱动程序的编写。WINDOWSCE的话容易入门点,但目前学LINUX的比较多,但难学一点,因为是免费开源的嘛!当然现在还有很多操作系统的,建议先弄懂一个。再弄其它。(注:这只是我个人学习ARM的见解,不一定适合每个人,希望对你有所帮助)不过摄像头和TFT稍微难理解一点。先弄简单的,就当单片机一样用,这阶段当然裸奔并不是ARM的精华部分,如果只是裸奔的话那么ARM就只能算个增强型
Ⅸ LINUX下C语言编程怎么打印日志
我们的程序一般都会产生输出信息。但是服务器程序一般却不希望输出信息到屏幕上,因为没有人盯着你的程序执行。所以我们要把一些信息写成日志文件,正常情况下运行程序的人不用关心日志里的内容,只有在出现问题的时候才会查看日志文件里的内容以确定问题所在。
但如果我们的程序要自己生成一个文件来保存日志却不是好主意,因为这一方面增加了维护程序运行的人的负担,另一方面自己维护起系统来也多有不便。
在Linux系统中有一个系统日志,通常放在/var/log目录下,比如文件名是syslog的,系统中的一些程序产生的日志信息都会存放到这个文件里。日志文件有固定的格式,比如第1列是消息产生的时间,第2列是机器名(因为日志记录程序支持远程连接),第3列是标记信息(一般就是程序名称)等。而且对应的有一些工具来对这个日志进行维护,比如通过轮回机制保证日志文件大小不会把磁盘空间占尽。所以我们把自己程序的信息也写到这个系统日志里是比较好的想法。
在GNU C语言库提供的内容中,有接口可以用来做这件事。用下面的命令查看:
nm -D /lib/libc.so.6 | grep log
可以看到一些调用:
000b9410Tcloselog
0008b870Tgetlogin
0008b960Tgetlogin_r
000d0180T__getlogin_r_chk
000bd190Tklogctl
00027450T__open_catalog
000b9380Topenlog
0008bae0Tsetlogin
000b8b80Tsetlogmask
000b9350Tsyslog
000b9320T__syslog_chk
000b92f0Tvsyslog
000b8da0T__vsyslog_chk
这里面的三个函数openlog, syslog, closelog是一套系统日志写入接口。另外那个vsyslog和syslog功能一样,只是参数格式不同。
程序的用法示例代码如下:
#include<syslog.h>
intmain(intargc,char**argv)
{
openlog("MyMsgMARK",LOG_CONS|LOG_PID,0);
syslog(LOG_DEBUG,
"'%s' ",
argv[0]);
closelog();
return0;
}
编译生成可执行程序后,运行一次程序将向/var/log/syslog文件添加一行信息如下:
Feb1208:48:38localhostMyMsgMARK[7085]:'./a.out'
Feb 12 08:48:38 localhost MyMsgMARK[7085]: This is a syslog test message generated by program './a.out'
LOG_CONS
.
LOG_NDELAY
Opentheconnectionimmediately(normally,).
LOG_NOWAIT
Don’.(TheGNUClibrarydoesnotcreatea
childprocess,.)
LOG_ODELAY
TheconverseofLOG_NDELAY;()iscalled.(Thisisthedefault,andneed
notbespecified.)
LOG_PERROR
(NotinSUSv3.)Printtostderraswell.
LOG_PID
IncludePIDwitheachmessage.
第三个参数指明记录日志的程序的类型。
syslog函数及参数
syslog函数用于把日志消息发给系统程序syslogd去记录,此函数原型是:
void syslog(int priority, const char *format, ...);
第一个参数是消息的紧急级别,第二个参数是消息的格式,之后是格式对应的参数。就是printf函数一样使用。
如果我们的程序要使用系统日志功能,只需要在程序启动时使用openlog函数来连接syslogd程序,后面随时用syslog函数写日志就行了。
另外,作为syslog的替代程序的新一代工具是syslog-ng,syslog-ng具有很强的网络功能,可以方便地把多台机器上的日志保存到一台中心日志服务器上。
Ⅹ 嵌入式开发板学习新手在iTOP4412开发板无界面linux操作系统使用CAN模块遇到问题,求解决方法
首先内核得配置上can的功能。这一点可以看一下在/dev下有没有can的节点 mpu,如果没有证明内核不支持 ; 如果内核支持的话,得先输入ifconfig can0 up,然后输入ifconfig才会有can的信息
