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的信息
