日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式微處理器
[導(dǎo)讀]▍很懶很操心 有一次,我在項(xiàng)目開發(fā)中想監(jiān)控某段空間數(shù)據(jù)的大小,即這段空間在MCU中非常有限,希望每個(gè)版本在集成軟件的時(shí)候都想獲取其使用了多少空間,防止某些愣頭青不珍惜內(nèi)存,亂塞東西。而這段空間,我定義了一個(gè)神一樣的結(jié)構(gòu)體映射到這個(gè)空間,即其他開


很懶很操

有一次,我在項(xiàng)目開發(fā)中想監(jiān)控某段空間數(shù)據(jù)的大小,即這段空間在MCU中非常有限,希望每個(gè)版本在集成軟件的時(shí)候都想獲取其使用了多少空間,防止某些愣頭青不珍惜內(nèi)存,亂塞東西。而這段空間,我定義了一個(gè)神一樣的結(jié)構(gòu)體映射到這個(gè)空間,即其他開發(fā)人員只要在結(jié)構(gòu)體增加元素即可(我使用洪荒之力將宏定義發(fā)揮到淋漓盡致才做到的,至于怎么實(shí)現(xiàn)的細(xì)節(jié)就不在這個(gè)文章討論了,后續(xù)再寫篇文章裝裝X)。

計(jì)算這個(gè)結(jié)構(gòu)體空間,要求:

  1. 在軟件集成階段就獲得這個(gè)結(jié)構(gòu)體大小,而不是MCU運(yùn)行的時(shí)候;(自動(dòng)執(zhí)行)

  2. 計(jì)算這個(gè)結(jié)構(gòu)體大小,不要增加刪除原程序代碼;(悄無(wú)聲息)

  3. 方便集成工程師使用,不增加使用難度;(簡(jiǎn)單易用)

  4. 不因?yàn)槿瞬僮鞯脑颍鴮?dǎo)致計(jì)算結(jié)果不準(zhǔn)確,即自動(dòng)化執(zhí)行輸出結(jié)果。(無(wú)人為干擾)

總之,做這件事的目的是:每次集成的時(shí)候自動(dòng)輸出結(jié)果(很懶),也不行交給其他小伙伴去手工計(jì)算,或者更改原來(lái)的結(jié)構(gòu)代碼去計(jì)算這個(gè)空間,怕其亂來(lái)搞壞了原來(lái)的代碼(很操心)。

再總之:能讓電腦干的活,干嘛要讓人去干!

于是,我就突發(fā)奇想,寫個(gè)腳本唄。

那么啥子腳本可以計(jì)算C語(yǔ)言的結(jié)構(gòu)體大小?

身為優(yōu)秀的嵌入式”工程師,對(duì)這種將C語(yǔ)言“嵌入”到腳本中的事情肯定是要研究一番的。

Note:為了方便描述,我將具體項(xiàng)目細(xì)節(jié)和裝X的過程隱去,并將這個(gè)神一樣的結(jié)構(gòu)體簡(jiǎn)化為:

 typedef struct
 {
     unsigned char item_a[2];
     unsigned char item_b[3];
     unsigned char item_c[5];
     unsigned char item_d[8];
     unsigned char item_e[33];
     unsigned char item_fxxk[1];
     unsigned char item_fxxxk[2];
     unsigned char item_fxxk_any[55];
     // add items here...
 }typeStructData;

將C/C++代碼嵌入Python

人生苦短,我用Python

溫馨提示,使用以下方法,請(qǐng)?zhí)崆鞍惭b:

  1. Python
  2. GCC(例如Windows上的MinGW)
  3. 用pip安裝pyembedc(pip install pyembedc

注意:Python的版本位數(shù)要跟GCC的對(duì)應(yīng),例如都選32位的。

方法1:Python調(diào)用exe方式

步驟:

  1. 在一個(gè)臨時(shí)C文件里,編寫臨時(shí)main函數(shù);

  2. 用GCC構(gòu)建編譯,生成exe;

  3. 通過腳本(此處選擇Python)調(diào)用運(yùn)行輸出結(jié)果;

  4. 刪除臨時(shí)C文件和exe文件。

接上代碼看看

 // struct.h
 
 typedef struct
 {
     unsigned char item_a[2];
     unsigned char item_b[3];
     unsigned char item_c[5];
     unsigned char item_d[8];
     unsigned char item_e[33];
     unsigned char item_fxxk[1];
     unsigned char item_fxxxk[2];
     unsigned char item_fxxk_any[55];
 }typeStructData;
 import os
 
 c_main = r'''
 #include <stdio.h>
 #include "struct.h"
 int main(void)
 {
    printf("size: %d\n", sizeof(typeStructData));
    return 0;
 }
 '''
 def cal_struct_size():
     f_c_main = 'xxxxsizeofstructxxxx.c'
     f_run = 'xxxxsizeofstructxxxx.exe'
     with open(f_c_main, 'w') as f: f.write(c_main)
     gcc_compile = "gcc %s -o %s"%(f_c_main, f_run)
 
     os.system(gcc_compile)
     os.system(f_run)
     if os.path.exists(f_c_main): os.remove(f_c_main)
     if os.path.exists(f_run): os.remove(f_run)
 
 if __name__ == "__main__":
     cal_struct_size()

方法2:Python調(diào)用lib方式

總覺得用Python調(diào)用exe的方式有點(diǎn)low,再進(jìn)一步,那就調(diào)用lib吧,例如調(diào)用.so內(nèi)的函數(shù)或者變量。

步驟跟方法1類似:

  1. 在一個(gè)臨時(shí)C文件里,編寫臨時(shí)main函數(shù);

  2. 用GCC構(gòu)建編譯,生成lib(.so);

  3. 通過Python調(diào)用運(yùn)行輸出結(jié)果;

  4. 刪除臨時(shí)C文件。

Python調(diào)用lib庫(kù)有個(gè)好處,可以調(diào)用其里面的具體函數(shù)等。

 // struct.c
 
 #include <stdio.h>
 
 typedef struct
 {
     unsigned char item_a[2];
     unsigned char item_b[3];
     unsigned char item_c[5];
     unsigned char item_d[8];
     unsigned char item_e[33];
     unsigned char item_fxxk[1];
     unsigned char item_fxxxk[2];
     unsigned char item_fxxk_any[55];
 }typeStructData;
 
 int get_struct_size(void)
 {
     return sizeof(typeStructData);
 }
 import ctypes
 import os
 
 os.system('gcc -shared -Wl,-soname,struct -o struct.so -fPIC struct.c')
 
 struct_size = ctypes.cdll.LoadLibrary('./struct.so')
 
 def cal_struct_size():
     s = struct_size.get_struct_size()
 
     print("size: %d"%s)
 
 if __name__ == "__main__":
     cal_struct_size()
     # if os.path.exists('struct.so'): os.remove('struct.so')

貌似有個(gè)小問題,如果想在腳本里面刪除這個(gè).so文件,會(huì)出現(xiàn)問題,因?yàn)闆]有辦法unload這個(gè).so。另外,關(guān)于這個(gè)話題,請(qǐng)參考:https://stackoverflow.com/questions/359498/how-can-i-unload-a-dll-using-ctypes-in-python

方法3:Python調(diào)用C源碼方式

調(diào)用exe和調(diào)用lib,都覺得很low,怎么辦,能不能直接插入C源碼呢?

那就用pyembedc吧,Python可以訪問C的變量,C也可以訪問Python的變量,是不是炫酷吊炸天。

例1,訪問C內(nèi)部變量

 # callstruct_inline1.py
 
 from pyembedc import C
 
 struct_str = r'''
    typedef struct
    {
        unsigned char item_a[2];
        unsigned char item_b[3];
        unsigned char item_c[5];
        unsigned char item_d[8];
        unsigned char item_e[33];
        unsigned char item_fxxk[1];
        unsigned char item_fxxxk[2];
        unsigned char item_fxxk_any[55];
    }typeStructData;
    struct_size = sizeof(typeStructData);
 
 '''
 struct_size = 0
 struct_f = C(struct_str)
 print('size: %d\n'%struct_size)

例2,訪問C內(nèi)部函數(shù)

 # callstruct_inline2.py
 
 from pyembedc import embed_c
 
 struct_str2 = r'''
    typedef struct
    {
        unsigned char item_a[2];
        unsigned char item_b[3];
        unsigned char item_c[5];
        unsigned char item_d[8];
        unsigned char item_e[33];
        unsigned char item_fxxk[1];
        unsigned char item_fxxxk[2];
        unsigned char item_fxxk_any[55];
    }typeStructData;
     
    int get_struct_size(void)
    {
        return sizeof(typeStructData);
    }
 '''
 struct_c = embed_c(struct_str2)
 print('size: %d\n'%struct_c.get_struct_size())

實(shí)際上,以上的操作,也是這個(gè)庫(kù)偷偷地調(diào)用了GCC來(lái)編譯C代碼的(只是不是顯式讓你看到而已),你不安裝對(duì)應(yīng)版本的GCC也是做不到的。

順便說是,這個(gè)pyembedc有幾個(gè)方式:

Functionspyembedc.C(string) -> intpyembedc.inline_c(string) -> intpyembedc.inline_c_precompile(string) -> int

These functions will compile string containing the C/C++ code or directives (see below) and then link dynamically and run the code.

string is C/C++ code that can be used within a function. It can contain any valid C/C++ expression that your compiler will support.

The C function will automatically provide references to all local Python variables for use in your code to read or write as if they were basic types or arrays.

The inline_c and inline_c_precompile fucntion will not provide references to local Python variables and thus is faster and consumes less memory.

pyembedc.embed_c(string) -> cdllpyembedc.embed_c_precompile(string) -> cdll

These functions are used to compile code but not execute immediately. They return a CDLL object (see the CDLL python module) that can be executed later.

更多內(nèi)容,請(qǐng)見:https://github.com/ftrias/pyembedc


將C/C++代碼嵌入Ruby

生活詩(shī)意,我用Ruby

能把C代碼塞進(jìn)Python,當(dāng)然也能塞進(jìn)Ruby。對(duì)于在Ruby上插入C源碼,給大家安利一個(gè)庫(kù)RubyInline。

Inline允許您在Ruby代碼中編寫外部代碼。它會(huì)自動(dòng)確定相關(guān)代碼是否已更改,并僅在必要時(shí)進(jìn)行構(gòu)建。然后將擴(kuò)展自動(dòng)加載到定義擴(kuò)展的類/模塊中。您甚至可以編寫額外的構(gòu)建器,使您可以用任何語(yǔ)言編寫Inline代碼。使用Inline :: C作為Module,并在Module#inline中查找所需的API。

RubyInline還有以下Features:

  • 快速,輕松地內(nèi)嵌在ruby腳本中的C或C ++代碼。

  • 可擴(kuò)展以與其他語(yǔ)言一起使用。

  • 紅寶石和C基本類型之間的自動(dòng)轉(zhuǎn)換* char,unsigned,unsigned int,char *,int,long,unsigned long

  • inline_c_raw用于自動(dòng)轉(zhuǎn)換不充分時(shí)。

  • 僅當(dāng)內(nèi)聯(lián)代碼已更改時(shí)才重新編譯。

  • 假裝是安全的。

  • 僅需要標(biāo)準(zhǔn)的ruby庫(kù),無(wú)需下載其他內(nèi)容。

 require "inline"
 class MyTest
     inline do |builder|
         builder.c "
            long factorial(int max) {
                int i=max, result=1;
                while (i >= 2) { result *= i--; }
                return result;
            }"
         end
 end
 t = MyTest.new()
 factorial_5 = t.factorial(5)
 require 'inline'
 class MyTest
     inline(:C) do |builder|
         builder.include '<iostream>'
         builder.add_compile_flags '-x c++', '-lstdc++'
         builder.c '
            void hello(int i) {
                while (i-- > 0) {
                    std::cout << "hello" << std::endl;
                }
            }'
     end
 end
 t = MyTest.new()
 t.hello(3)
 

是不是很好玩,是不是很想試試?但是我告訴你,我在Windows上沒搞成功,但在Linux上搞起來(lái)了。應(yīng)了網(wǎng)上某句話:想學(xué)Ruby,就用Linux吧,別在Windows上瞎折騰。話說回來(lái),這個(gè)嵌入式C源碼的用法,個(gè)人感覺Ruby的比Python的簡(jiǎn)潔直觀。該用哪種方法,看實(shí)際需要吧。更多內(nèi)容,詳見:https://github.com/seattlerb/rubyinline


總結(jié)

想將C/C++塞進(jìn)腳本,需要借助GCC,它才是讓你裝逼讓你飛的前提條件。


本文授權(quán)轉(zhuǎn)載自公眾號(hào)“嵌入式軟件實(shí)戰(zhàn)派”,作者實(shí)戰(zhàn)派師姐


-END-




推薦閱讀



【01】嵌入式系統(tǒng)中常用的IIC與SPI,這兩種通訊方式該怎么選?
【02】嵌入式必看:Linux內(nèi)存管理那些事兒
【03】嵌入式項(xiàng)目是如何評(píng)估系統(tǒng)所需的RAM和ROM用量的?
【04】嵌入式和單片機(jī)不一樣?那它們的區(qū)別在哪?
【05】嵌入式開發(fā)碰到無(wú)法解決的問題?編程的凹凸性有妙用?。ǜ?a href="/tags/C代碼" target="_blank">C代碼


免責(zé)聲明:整理文章為傳播相關(guān)技術(shù),版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系刪除

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

嵌入式ARM

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀

高性能計(jì)算領(lǐng)域,分支預(yù)測(cè)錯(cuò)誤導(dǎo)致的流水線停頓(Pipeline Stall)是制約CPU性能的關(guān)鍵因素之一?,F(xiàn)代處理器通過復(fù)雜的分支預(yù)測(cè)機(jī)制(如GShare、TAGE等)將預(yù)測(cè)準(zhǔn)確率提升至95%以上,但剩余5%的錯(cuò)誤仍會(huì)...

關(guān)鍵字: C代碼 pipeline stall

在嵌入式系統(tǒng)開發(fā)中,時(shí)間戳的獲取是一項(xiàng)基礎(chǔ)而關(guān)鍵的功能。時(shí)間戳,即表示某一瞬間的時(shí)間點(diǎn)的唯一標(biāo)識(shí),通常以自某一固定時(shí)間點(diǎn)(如Unix紀(jì)元,即1970年1月1日00:00:00 UTC)以來(lái)的秒數(shù)或毫秒數(shù)表示。它不僅在日志...

關(guān)鍵字: 嵌入式系統(tǒng)開發(fā) C代碼 時(shí)間戳 Unix

如何開始編寫一個(gè)簡(jiǎn)單的單片機(jī)程序呢?接下來(lái)就來(lái)介紹一下步驟和方法以便更快更好的編寫出來(lái)單片機(jī)程序。

關(guān)鍵字: C代碼 編程序

關(guān)注、星標(biāo)公眾號(hào),直達(dá)精彩內(nèi)容文章來(lái)源:segmentfault作者:Ethson【導(dǎo)讀】:樹是數(shù)據(jù)結(jié)構(gòu)中的重中之重,尤其以各類二叉樹為學(xué)習(xí)的難點(diǎn)。在面試環(huán)節(jié)中,二叉樹也是必考的模塊。本文主要講二叉樹操作的相關(guān)知識(shí),梳理...

關(guān)鍵字: C代碼 BSP ORDER WHILE

【導(dǎo)讀】:樹是數(shù)據(jù)結(jié)構(gòu)中的重中之重,尤其以各類二叉樹為學(xué)習(xí)的難點(diǎn)。在面試環(huán)節(jié)中,二叉樹也是必考的模塊。本文主要講二叉樹操作的相關(guān)知識(shí),梳理面試常考的內(nèi)容。請(qǐng)大家跟隨小編一起來(lái)復(fù)習(xí)吧。本文針對(duì)面試中常見的二叉樹操作做個(gè)總結(jié)...

關(guān)鍵字: C代碼 ORDER WHILE RETURN

關(guān)注「Linux大陸」,一起進(jìn)步!繼?300來(lái)行代碼帶你實(shí)現(xiàn)一個(gè)能跑的最小Linux文件系統(tǒng)?之后,我們來(lái)看看如何60行C代碼實(shí)現(xiàn)一個(gè)shell!在實(shí)現(xiàn)它之前,先看看這樣做的意義。美是有目共睹的。Unix之美,稍微體會(huì),...

關(guān)鍵字: shell C代碼

來(lái)源:公眾號(hào)【編程珠璣】作者:守望先生前言如何在C代碼中調(diào)用寫好的C接口?你可能會(huì)奇怪,C不是兼容C嗎?直接調(diào)用不就可以了?這里我們先按下不表,先看看C如何調(diào)用C代碼接口。C如何調(diào)用C接口為什么會(huì)有這樣的情況呢?想象一下...

關(guān)鍵字: C代碼

今天跟大家分享三種表驅(qū)動(dòng)設(shè)計(jì)的方法,都非常的精妙,值得收藏和細(xì)品。

關(guān)鍵字: 表驅(qū)動(dòng) 靜態(tài)結(jié)構(gòu)體 C代碼

為了優(yōu)化鉆井流程并降低作業(yè)成本,Baker Hughes的動(dòng)力學(xué)與遙測(cè)(Dynamics & Telemetry)小組開發(fā)了一個(gè)序列預(yù)測(cè)算法,用于在鉆井作業(yè)期間快速可靠的解碼井下數(shù)據(jù)。這個(gè)已集成

關(guān)鍵字: C代碼 編碼 自動(dòng)代碼生成 馬爾可夫鏈

  本文講解的是飛思卡爾軟件開發(fā)C語(yǔ)言編碼規(guī)范。來(lái)自于痞子衡嵌入式公眾號(hào),下面是編碼規(guī)范原文: 1.引言   制定此編碼風(fēng)格指導(dǎo)手冊(cè)的目的是為了使按此規(guī)范編寫出的C/C++代碼極易被閱讀和理解。 2.與其他編碼風(fēng)格對(duì)比...

關(guān)鍵字: 軟件開發(fā) MCU 半導(dǎo)體 C代碼
關(guān)閉