精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

淺談嵌入式中的C語言編程技術分析

FPGA那點事兒 ? 來源:STM32嵌入式開發 ? 作者:STM32嵌入式開發 ? 2021-08-19 14:50 ? 次閱讀

嵌入式產品的可靠性自然與硬件密不可分,但在硬件確定、并且沒有第三方測試的前提下,使用防御性編程思想寫出的代碼,往往具有更高的穩定性。

防御性編程首先需要認清C語言的種種缺陷和陷阱,C語言對于運行時的檢查十分弱小,需要程序員謹慎的考慮代碼,在必要的時候增加判斷;防御性編程的另一個核心思想是假設代碼運行在并不可靠的硬件上,外接干擾有可能會打亂程序執行順序、更改RAM存儲數據等等。

1具有形參的函數,需判斷傳遞來的實參是否合法

程序員可能無意識的傳遞了錯誤參數;外界的強干擾可能將傳遞的參數修改掉,或者使用隨機參數意外的調用函數,因此在執行函數主體前,需要先確定實參是否合法。

4c99c0fa-fd3c-11eb-9bcf-12bb97331649.png

2仔細檢查函數的返回值

對函數返回的錯誤碼,要進行全面仔細處理,必要時做錯誤記錄。

4ca27a06-fd3c-11eb-9bcf-12bb97331649.png

3防止指針越界

如果動態計算一個地址時,要保證被計算的地址是合理的并指向某個有意義的地方。特別對于指向一個結構或數組的內部的指針,當指針增加或者改變后仍然指向同一個結構或數組。

4防止數組越界

數組越界的問題前文已經講述的很多了,由于C不會對數組進行有效的檢測,因此必須在應用中顯式的檢測數組越界問題。下面的例子可用于中斷接收通訊數據。

4cbb786c-fd3c-11eb-9bcf-12bb97331649.png

在使用一些庫函數時,同樣需要對邊界進行檢查,比如下面的memset(RecBuf,0,len)函數把RecBuf指指向的內存區的前len個字節用0填充,如果不注意len的長度,就會將數組RecBuf之外的內存區清零:

4ce8cf2e-fd3c-11eb-9bcf-12bb97331649.png

5數學數運算

5.1除法運算,只檢測除數為零就可靠嗎?

除法運算前,檢查除數是否為零幾乎已經成為共識,但是僅檢查除數是否為零就夠了嗎?

考慮兩個整數相除,對于一個signed long類型變量,它能表示的數值范圍為:-2147483648 ~+2147483647,如果讓-2147483648/ -1,那么結果應該是+2147483648,但是這個結果已經超出了signedlong所能表示的范圍了。所以,在這種情況下,除了要檢測除數是否為零外,還要檢測除法是否溢出。

 #include <limits.h>  
   signed long sl1,sl2,result; /*初始化sl1和sl2*/   
  if((sl2==0)||(sl1==LONG_MIN && sl2==-1)) {  
   //處理錯誤     } else  
  {     result = sl1 / sl2; }

5.2檢測運算溢出

整數的加減乘運算都有可能發生溢出,在討論未定義行為時,給出過一個有符號整形加法溢出判斷代碼,這里再給出一個無符號整形加法溢出判斷代碼段:

 #include      unsigned int a,b,result; /*初始化a,b*/     if(UINT_MAX-a {     //處理溢出     } else    {     result=a+b; }

嵌入式硬件一般沒有浮點處理器,浮點數運算在嵌入式也比較少見并且溢出判斷嚴重依賴C庫支持,這里不討論。

5.3檢測移

在討論未定義行為時,提到有符號數右移、移位的數量是負值或者大于操作數的位數都是未定義行為,也提到不對有符號數進行位操作,但要檢測移位的數量是否大于操作數的位數。下面給出一個無符號整數左移檢測代碼段:

 unsigned int ui1; unsigned int ui2; unsigned int uresult; /*初始化ui1,ui2*/   if(ui2>=sizeof(unsigned int)*CHAR_BIT) {     //處理錯誤   } else   {     uresult=ui1< }

6如果有硬件看門狗,則使用它

在其它一切措施都失效的情況下,看門狗可能是最后的防線。它的原理特別簡單,但卻能大大提高設備的可靠性。如果設備有硬件看門狗,一定要為它編寫驅動程序。

  • 要盡可能早的開啟看門狗

這是因為從上電復位結束到開啟看門狗的這段時間內,設備有可能被干擾而跳過看門狗初始化程序,導致看門狗失效。盡可能早的開啟看門狗,可以降低這種概率;

  • 不要在中斷中喂狗,除非有其他聯動措施

在中斷程序喂狗,由于干擾的存在,程序可能一直處于中斷之中,這樣會導致看門狗失效。如果在主程序中設置標志位,中斷程序喂狗時與這個標志位聯合判斷,也是允許的;

  • 喂狗間隔跟產品需求有關,并非特定的時間

產品的特性決定了喂狗間隔。對于不涉及安全性、實時性的設備,喂狗間隔比較寬松,但間隔時間不宜過長,否則被用戶感知到,是影響用戶體驗的。對于設計安全性、有實時控制類的設備,原則是盡可能快的復位,否則會造成事故。

克萊門汀號在進行第二階段的任務時,原本預訂要從月球飛行到太空深處的Geographos小行星進行探勘,然而這艘太空探測器在飛向小行星時卻由于一個軟件缺陷而使其中斷運作20分鐘,不但未能到達小行星,也因為控制噴嘴燃燒了11分鐘使電力供應降低,無法再透過遠端控制探測器,最終結束這項任務,但也導致了資源與資金的浪費。

“克萊門汀太空任務失敗這件事讓我感到十分震驚,它其實可以透過硬件中一款簡單的看門狗計時器避免掉這項意外,但由于當時的開發時間相當緊縮,程序設計人員沒時間編寫程序來啟動它,”Ganssle說。

遺憾的是,1998年發射的近地號太空船(NEAR)也遇到了相同的問題。由于編程人員并未采納建議,因此,當推進器減速器系統故障時,29公斤的儲備燃料也隨之報銷──這同樣是一個本來可經由看門狗定時器編程而避免的問題,同時也證明要從其他程序設計人員的錯誤中學習并不容易。

7 關鍵數據儲存多個備份,取數據采用“表決法”

RAM中的數據在受到干擾情況下有可能被改變,對于系統關鍵數據應該進行保護。關鍵數據包括全局變量、靜態變量以及需要保護的數據區域。備份數據與原數據不應該處于相鄰位置,因此不應由編譯器默認分配備份數據位置,而應該由程序員指定區域存儲。

可以將RAM分為3個區域,第一個區域保存原碼,第二個區域保存反碼,第三個區域保存異或碼,區域之間預留一定量的“空白”RAM作為隔離。可以使用編譯器的“分散加載”機制將變量分別存儲在這些區域。需要進行讀取時,同時讀出3份數據并進行表決,取至少有兩個相同的那個值。

假如設備的RAM從0x1000_0000開始,我需要在RAM的0x1000_0000~0x10007FFF內存儲原碼,在0x1000_9000~0x10009FFF內存儲反碼,在0x1000_B000~0x1000BFFF內存儲0xAA的異或碼,編譯器的分散加載可以設置為:

 LR_IROM1 0x00000000 0x00080000  {   
 ; load region size_region
ER_IROM10x000000000x00080000
{;loadaddress=execution address  
  *.o (RESET, +First)    *(InRoot$$Sections)   
 .ANY (+RO)   }   RW_IRAM1 0x10000000 0x00008000
  {  ;保存原碼    .ANY (+RW +ZI )  
 }   RW_IRAM3 0x10009000 0x00001000{
    ;保存反碼    .ANY (MY_BK1)  
 }   RW_IRAM2 0x1000B000 0x00001000  
{  ;保存異或碼    .ANY (MY_BK2)  
 } }

如果一個關鍵變量需要多處備份,可以按照下面方式定義變量,將三個變量分別指定到三個不連續的RAM區中,并在定義時按照原碼、反碼、0xAA的異或碼進行初始化。

 uint32  plc_pc=0;                                                       //原碼   __attribute__((section("MY_BK1"))) uint32 plc_pc_not=~0x0;              //反碼   __attribute__((section("MY_BK2"))) uint32 plc_pc_xor=0x0^0xAAAAAAAA;    //異或碼

當需要寫這個變量時,這三個位置都要更新;讀取變量時,讀取三個值做判斷,取至少有兩個相同的那個值。

為什么選取異或碼而不是補碼?這是因為MDK的整數是按照補碼存儲的,正數的補碼與原碼相同,在這種情況下,原碼和補碼是一致的,不但起不到冗余作用,反而對可靠性有害。比如存儲的一個非零整數區因為干擾,RAM都被清零,由于原碼和補碼一致,按照3取2的“表決法”,會將干擾值0當做正確的數據。

8 對非易失性存儲器進行備份存

非易失性存儲器包括但不限于Flash、EEPROM、鐵電。僅僅將寫入非易失性存儲器中的數據再讀出校驗是不夠的。強干擾情況下可能導致非易失性存儲器內的數據錯誤,在寫非易失性存儲器的期間系統掉電將導致數據丟失,因干擾導致程序跑飛到寫非易失性存儲器函數中,將導致數據存儲紊亂。

一種可靠的辦法是將非易失性存儲器分成多個區,每個數據都將按照不同的形式寫入到這些分區中,需要進行讀取時,同時讀出多份數據并進行表決,取相同數目較多的那個值。

9 軟件

對于初始化序列或者有一定先后順序的函數調用,為了保證調用順序或者確保每個函數都被調用,我們可以使用環環相扣,實質上這也是一種軟件鎖。此外對于一些安全關鍵代碼語句(是語句,而不是函數),可以給它們設置軟件鎖,只有持有特定鑰匙的,才可以訪問這些關鍵代碼。也可以通俗的理解為,關鍵安全代碼不能按照單一條件執行,要額外的多設置一個標志。

比如,向Flash寫一個數據,我們會判斷數據是否合法、寫入的地址是否合法,計算要寫入的扇區。之后調用寫Flash子程序,在這個子程序中,判斷扇區地址是否合法、數據長度是否合法,之后就要將數據寫入Flash。

由于寫Flash語句是安全關鍵代碼,所以程序給這些語句上鎖:必須具有正確的鑰匙才可以寫Flash。這樣即使是程序跑飛到寫Flash子程序,也能大大降低誤寫的風險。

  • * 名稱:RamToFlash() * 功能:復制RAM的數據到FLASH,命令代碼51。
  • * 入口參數:dst 目標地址,即FLASH起始地址。以512字節為分界
  • * src 源地址,即RAM地址。地址必須字對齊 * no 復制字節個數,為512/1024/4096/8192 * ProgStart 軟件鎖標志 * 出口參數:IAP返回值(paramout緩沖區) CMD_SUCCESS,SRC_ADDR_ERROR,DST_ADDR_ERROR, SRC_ADDR_NOT_MAPPED,DST_ADDR_NOT_MAPPED,COUNT_ERROR,BUSY,未選擇扇區 ****************************************************************/
  • void RamToFlash(uint32 dst, uint32 src, uint32 no,uint8 ProgStart)
  • { PLC_ASSERT("Sector number",(dst>=0x00040000)&&(dst<=0x0007FFFF)); PLC_ASSERT("Copy bytes number is 512",(no==512)); PLC_ASSERT("ProgStart==0xA5",(ProgStart==0xA5)); paramin[0] = IAP_RAMTOFLASH; // 設置命令字 paramin[1] = dst; // 設置參數 paramin[2] = src; paramin[3] = no; paramin[4] = Fcclk/1000;
  • if(ProgStart==0xA5)
  • //只有軟件鎖標志正確時,才執行關鍵代碼
  • { iap_entry(paramin, paramout); // 調用IAP服務程序 ProgStart=0; } else { paramout[0]=PROG_UNSTART; } }

該程序段是編程lpc1778內部Flash,其中調用IAP程序的函數iap_entry(paramin, paramout)是關鍵安全代碼,所以在執行該代碼前,先判斷一個特定設置的安全鎖標志ProgStart,只有這個標志符合設定值,才會執行編程Flash操作。如果因為意外程序跑飛到該函數,由于ProgStart標志不正確,是不會對Flash進行編程的。

10 通信

通訊線上的數據誤碼相對嚴重,通訊線越長,所處的環境越惡劣,誤碼會越嚴重。拋開硬件和環境的作用,我們的軟件應能識別錯誤的通訊數據。對此有一些應用措施:

  • 制定協議時,限制每幀的字節數;

每幀字節數越多,發生誤碼的可能性就越大,無效的數據也會越多。對此以太網規定每幀數據不大于1500字節,高可靠性的CAN收發器規定每幀數據不得多于8字節,對于RS485,基于RS485鏈路應用最廣泛的Modbus協議一幀數據規定不超過256字節。因此,建議制定內部通訊協議時,使用RS485時規定每幀數據不超過256字節;

  • 使用多種校驗

編寫程序時應使能奇偶校驗,每幀超過16字節的應用,建議至少編寫CRC16校驗程序。

  • 增加額外判斷

1)增加緩沖區溢出判斷。這是因為數據接收多是在中斷中完成,編譯器檢測不出緩沖區是否溢出,需要手動檢查,在上文介紹數據溢出一節中已經詳細說明。

2)增加超時判斷。當一幀數據接收到一半,長時間接收不到剩余數據,則認為這幀數據無效,重新開始接收。可選,跟不同的協議有關,但緩沖區溢出判斷必須實現。這是因為對于需要幀頭判斷的協議,上位機可能發送完幀頭后突然斷電,重啟后上位機是從新的幀開始發送的,但是下位機已經接收到了上次未發送完的幀頭,所以上位機的這次幀頭會被下位機當成正常數據接收。這有可能造成數據長度字段為一個很大的值,填滿該長度的緩沖區需要相當多的數據(比如一幀可能1000字節),影響響應時間;另一方面,如果程序沒有緩沖區溢出判斷,那么緩沖區很可能溢出,后果是災難性的。

  • 重傳機制

如果檢測到通訊數據發生了錯誤,則要有重傳機制重新發送出錯的幀。

11 開關量輸入的檢測、確認

開關量容易受到尖脈沖干擾,如果不進行濾除,可能會造成誤動作。一般情況下,需要對開關量輸入信號進行多次采樣,并進行邏輯判斷直到確認信號無誤為止。

12 開關量輸出

開關信號簡單的一次輸出是不安全的,干擾信號可能會翻轉開關量輸出的狀態。采取重復刷新輸出可以有效防止電平的翻轉。

13 初始化信息的保存和恢復

微處理器寄存器值也可能會因外界干擾而改變,外設初始化值需要在寄存器中長期保存,最容易被破壞。由于Flash中的數據相對不易被破壞,可以將初始化信息預先寫入Flash,待程序空閑時比較與初始化相關的寄存器值是否被更改,如果發現非法更改則使用Flash中的值進行恢復。

公司目前使用的4.3寸LCD顯示屏抗干擾能力一般。如果顯示屏與控制器之間的排線距離過長或者對使用該顯示屏的設備打靜電或者脈沖群,顯示屏有可能會花屏或者白屏。

對此,我們可以將初始化顯示屏的數據保存在Flash中,程序運行后,每隔一段時間從顯示屏的寄存器讀出當前值和Flash存儲的值相比較,如果發現兩者不同,則重新初始化顯示屏。下面給出校驗源碼,僅供參考。

定義數據結構:

4d0349b2-fd3c-11eb-9bcf-12bb97331649.png

定義const修飾的結構體變量,存儲LCD部分寄存器的初始值,這個初始值跟具體的應用初始化有關,不一定是表中的數據,通常情況下,這個結構體變量被存儲到Flash中。

 /*LCD部分寄存器設置值列表*/  
 lcd_redu_list_struct const lcd_redu_list_str[]= { 

  {SSD1963_Get_Address_Mode,{0x20}                                  
 ,1}, /*1*/    {SSD1963_Get_Pll_Mn      
,{0x3b,0x02,0x04}                      
   ,3}, /*2*/   
 {SSD1963_Get_Pll_Status 
 ,{0x04}                              
     ,1}, /*3*/   
 {SSD1963_Get_Lcd_Mode  
  ,{0x24,0x20,0x01,0xdf,0x01,0x0f,0x00}    
 ,7}, /*4*/   
 {SSD1963_Get_Hori_Period ,{0x02,0x0c,0x00,0x2a,0x07,0x00,0x00,0x00},8}, /*5*/  
  {SSD1963_Get_Vert_Period ,{0x01,0x1d,0x00,0x0b,0x09,0x00,0x00}    
 ,7}, /*6*/    {SSD1963_Get_Power_Mode  ,{0x1c}                                  
 ,1}, /*7*/    {SSD1963_Get_Display_Mode,{0x03}                                 
  ,1}, /*8*/    {SSD1963_Get_Gpio_Conf   ,{0x0F,0x01}                       
       ,2}, /*9*/   
 {SSD1963_Get_Lshift_Freq ,{0x00,0xb8}                         
     ,2}, /*10*/ };

實現函數如下所示,函數會遍歷結構體變量中的每一個命令,以及每一個命令下的初始值,如果有一個不正確,則跳出循環,執行重新初始化和恢復措施。這個函數中的MY_DEBUGF宏是我自己的調試函數,使用串口打印調試信息,在接下來的第五部分將詳細敘述。

通過這個函數,我可以長時間監控顯示屏的哪些命令、哪些位容易被干擾。程序里使用了一個被妖魔化的關鍵字:goto。大多數C語言書籍對goto關鍵字談之色變,但你應該有自己的判斷。在函數內部跳出多重循環,除了goto關鍵字,又有哪種方法能如此簡潔高效!

 /**  * lcd 顯示冗余  * 每隔一段時間調用該程序一次  */  
 void lcd_redu(void)   {  
   uint8_t  tmp[8];   
  uint32_t i,j;   
  uint32_t lcd_init_flag;   
  lcd_init_flag =0;
for(i=0;i<sizeof(lcd_redu_list_str)/sizeof(lcd_redu_list_str[0]);i+)     
{         LCD_SendCommand(lcd_redu_list_str[i].lcd_command);         
uyDelay(10);     
    for(j=0;j<lcd_redu_list_str[i].lcd_value_num;j++)     
    {             tmp[j]=LCD_ReadData();       
      if(tmp[j]!=lcd_redu_list_str[i].lcd_get_value[j])       
      {                 lcd_init_flag=0x55;                
 MY_DEBUGF(MENU_DEBUG,("讀lcd寄存器值與預期不符,命令為:0x%x,第%d個參數,          
   該參數正確值為:0x%x,實際讀出值為:0x%xn",lcd_redu_list_str[i].lcd_command,j+1,       
      lcd_redu_list_str[i].lcd_get_value[j],tmp[j]));                
 goto handle_lcd_init;             }         }     } 
    handle_lcd_init:  
   if(lcd_init_flag==0x55)   
  {         //重新初始化LCD        
   //一些必要的恢復措施       } }

14 陷阱


對于8051內核單片機,由于沒有相應的硬件支持,可以用純軟件設置軟件陷阱,用來攔截一些程序跑飛。對于ARM7或者Cortex-M系列單片機,硬件已經內建了多種異常,軟件需要根據硬件異常來編寫陷阱程序,用來快速定位甚至恢復錯誤。

15 阻塞處理

有時候程序員會使用while(!flag);語句阻塞在此等待標志flag改變,比如串口發送時用來等待一字節數據發送完成。這樣的代碼時存在風險的,如果因為某些原因標志位一直不改變則會造成系統死機。

一個良好冗余的程序是設置一個超時定時器,超過一定時間后,強制程序退出while循環。

2003年8月11日發生的W32.Blaster.Worm蠕蟲事件導致全球經濟損失高達5億美元,這個漏洞是利用了Windows分布式組件對象模型的遠程過程調用接口中的一個邏輯缺陷:在調用GetMachineName()函數時,循環只設置了一個不充分的結束條件。

原代碼簡化如下所示:

4d20a930-fd3c-11eb-9bcf-12bb97331649.png

軟發布的安全補丁MS03-026解決了這個問題,為GetMachineName()函數設置了充分終止條件。一個解決代碼簡化如下所示(并非微軟補丁代碼):

 HRESULT GetMachineName( WCHAR *pwszPath,
   WCHARwszMachineName[MAX_COMPUTTERNAME_LENGTH_FQDN+1]) {   
     WCHAR *pwszServerName = wszMachineName;      
  WCHAR *pwszTemp = pwszPath + 2;      
  WCHAR *end_addr = pwszServerName +MAX_COMPUTTERNAME_LENGTH_FQDN;

while((*pwszTemp!=L’\’)&&(*pwszTemp!=L’’)&&(pwszServerName            
  *pwszServerName++= *pwszTemp++;       
 /*… */   }

編輯:hfy


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5068

    文章

    19021

    瀏覽量

    303352
  • C語言
    +關注

    關注

    180

    文章

    7599

    瀏覽量

    136214

原文標題:嵌入式開發中的防御性C語言編程

文章出處:【微信號:gh_94c30763133f,微信公眾號:FPGA那點事兒】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    嵌入式編程語言

    嵌入式編程語言隨著社會的飛速發展,IT技術已經進入高速發展階段,互聯網正在逐步向物聯網科技時代。發展。物聯網通過智能感知、識別
    發表于 11-08 06:10

    基于ARM的嵌入式系統與C語言編程的結合

    嵌入式平臺上進行C語言編寫系統軟件和應用軟件的方法,希望為軟件編程人員提供一些思考。隨著計算機技術尤其是計算機信息控制
    發表于 12-14 08:49

    SQL編程技術的特點有哪些

    SQL編程技術可以有效的克服SQL語言實現復雜應用方面的不足,提高應用系統和數據管理系統間的互操作性。SQL的特點之一是在交互嵌入式二種不同的使用方式下, SQL的語法結構基本上是
    發表于 12-22 07:04

    基于嵌入式實時操作系統的編程技術之資源同步介紹

    《基于嵌入式實時操作系統的編程技術》筆記清單:第三章任務劃分.《基于嵌入式實時操作系統的編程技術》筆記清單:第四章任務設計.《基于嵌入式實時
    發表于 12-22 06:30

    嵌入式系統高級C語言編程

    嵌入式系統高級C語言編程》將以實際項目中的代碼作實例來進行介紹,詳細分析嵌入式系統開發中程序
    發表于 10-27 16:36 ?4713次閱讀

    嵌入式c語言編程(由淺入深)

    本內容詳細介紹了嵌入式c語言編程的各項知識,包括嵌入式c語言
    發表于 11-02 14:37 ?0次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>c</b><b class='flag-5'>語言</b><b class='flag-5'>編程</b>(由淺入深)

    嵌入式C編程

    嵌入式C編程,非常有用的資料,介紹嵌入式C語言編程
    發表于 12-29 17:29 ?0次下載

    C語言嵌入式系統編程教程

    C語言嵌入式系統編程教程
    發表于 01-16 13:54 ?36次下載

    嵌入式c編程語言入門與深入

    嵌入式c編程語言入門與深入
    發表于 10-24 08:38 ?61次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>c</b><b class='flag-5'>編程</b><b class='flag-5'>語言</b>入門與深入

    關于嵌入式C語言它有些什么意義

    目前數控技術和智能裝備等技術都得到了廣泛的關注。無論是數控技術還是智能裝備等相關技術,都離不開嵌入式編程
    發表于 07-12 17:04 ?2248次閱讀

    嵌入式DSP系統C語言硬件編程技術簡介

    嵌入式DSP系統C語言硬件編程技術簡介(嵌入式開發環境配置)-該文檔為嵌入式DSP系統
    發表于 07-30 09:14 ?7次下載
    <b class='flag-5'>嵌入式</b>DSP系統<b class='flag-5'>C</b><b class='flag-5'>語言</b>硬件<b class='flag-5'>編程技術</b>簡介

    嵌入式DSP系統C語言硬件編程技術總結

    嵌入式DSP系統C語言硬件編程技術總結(北京嵌入式開發招聘)-該文檔為嵌入式DSP系統
    發表于 07-30 12:55 ?11次下載
    <b class='flag-5'>嵌入式</b>DSP系統<b class='flag-5'>C</b><b class='flag-5'>語言</b>硬件<b class='flag-5'>編程技術</b>總結

    嵌入式DSP系統C語言硬件編程技術

    嵌入式DSP系統C語言硬件編程技術(計算機三級嵌入式開發技術)-該文檔為
    發表于 07-30 14:04 ?27次下載
    <b class='flag-5'>嵌入式</b>DSP系統<b class='flag-5'>C</b><b class='flag-5'>語言</b>硬件<b class='flag-5'>編程技術</b>

    C語言嵌入式Linux高級編程

    C語言本質上是編程語言的“通用語言”,在今天仍具有極大的影響力。那么,C
    發表于 11-02 11:21 ?24次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>嵌入式</b>Linux高級<b class='flag-5'>編程</b>

    c語言嵌入式編程

    比較詳盡的嵌入式C語言解答和分析
    發表于 03-10 14:53 ?161次下載