01 、前言
大家好,我是XX,來自湖南XX學院,電子信息18級,也曾在創(chuàng)新基地控制組學習過兩三年,畢業(yè)后就職于一家芯片原廠的解決方案部,擔任驅動工程師的職位,算上實習期,我的工作時長已有兩年。在此我想將這兩年期間學習與積累到的一些經(jīng)驗輸出出來,與大家一同分享。
知識面有限,只能簡單介紹一些驅動開發(fā)方向的一些經(jīng)驗,且由于經(jīng)驗尚淺,文中難免會有一些疏漏和錯誤之處,還請大家積極地批評指正。
02 、Intro
工作之后我也時長回憶起在基地學習的時光,那時主要還是學習MCU相關,使用的是ST和TI家族的芯片,移植庫函數(shù)或者自行編寫驅動庫,燒錄到片內(nèi)flash上,驅動不同的外設,搭載一些如PID,卡爾曼濾波等算法,加入一些邏輯上的業(yè)務代碼,即可做出一些不錯的“小產(chǎn)品”出來。
今天來看,這樣的開發(fā)歷程更像是“全棧式”的開發(fā),因為這個過程不僅覆蓋了驅動部分的移植,也包括了功能,也即應用部分的開發(fā),這種開發(fā)路子常見于個人開發(fā)者,或是規(guī)模非常小的公司。一般情況下,工程量到達一定規(guī)模時,就會將二者分離到不同的崗位上來,各司其職。
然而,當前大部分公司依然不會保留太多單純的驅動開發(fā)崗位,更多得還是BSP和應用部分,大多數(shù)驅動開發(fā)崗位還是存在與供應關系的上游,也即芯片原廠,不管是MCU還是其他高端的SoC,芯片驅動多數(shù)都被原廠包圓了,下游的廠商多數(shù)都是在做BSP級別的開發(fā),以及應用開發(fā)(甚至有些小公司連BSP都沒有,例如我司的一些客戶...,都讓原廠負責了)也就是說,過去我是Consumer,而現(xiàn)在,我是Provider,負責為我司設計出品的芯片提供所有的Firmware,驅動代碼,以及SDK等。
總的來說,驅動這個崗位所要負責的內(nèi)容以及工作難度,在不同的企業(yè)類型,呈現(xiàn)這樣的一個關系:芯片原廠 > 方案廠 > 模組廠 > 板卡廠 > ?其他應用廠商。
03 、嘗試下細說原廠的驅動開發(fā)
為了更加具體的體現(xiàn)出芯片原廠的驅動開發(fā)在做些什么,下面我將逐步帶大家過一遍一顆芯片從設計到Bringup,再到交付完整的SDK包到客戶手中,到底經(jīng)歷了哪些環(huán)節(jié)。驅動開發(fā)者,在其中又做了哪些努力。
一般性的芯片開發(fā)流程:
芯片定義:指定芯片的規(guī)格(芯片spec)
芯片制造:設計好之后,就要送到foundry(代工廠)加工制造,(晶圓)
芯片測封:先對晶圓進行中測,然后進行劃片封裝,最后對封裝后的芯片進行成測。確保不會由生產(chǎn)環(huán)節(jié)引入錯誤。
芯片驗證:將芯片焊接到預先設計好的電路板上,裝配成機器并加載軟件,然后開始驗證。
其中,我們十分關注芯片設計與芯片驗證環(huán)節(jié)。芯片設計的周期通常來說會非常漫長,這個時間段是IC設計工程師大展拳腳的時候,他們也像軟件工程師一樣,需要對設計出的成果作調(diào)試,驗證。隨著大規(guī)模集成電路設計復雜性的逐漸提升,芯片驗證面臨的資金與時間的挑戰(zhàn)也變的越來越大,芯片的驗證階段占據(jù)了整個芯片開發(fā)的大部分時間。從芯片需求定義、功能設計開發(fā)到物理實現(xiàn)制造,每個環(huán)節(jié)都需要進行大量的驗證。早期開發(fā)者想驗證芯片的設計是否符合預設,只有等待漫長的模擬結果,或是等待流片成果。時間成本和經(jīng)濟成本都較高。
現(xiàn)如今驗證方法也越來越多,例如:邏輯仿真(功能驗證),形式驗證,原型驗證。功能驗證基于軟件,驗證成本較低,驗證環(huán)境方便,但性能較差;形式驗證為靜態(tài)驗證方式,但不可仿真DUT的一些動態(tài)行為。其中,大多公司都會選擇先在SoC驗證部門,進行邏輯仿真驗證,然后再交由基礎軟件開發(fā)部門,使用FPGA原型驗證的手段,對其進行二次驗證覆蓋。
FPGA原型驗證是一種成熟的技術,用于通過將RTL移植到現(xiàn)場可編程門陣列(FPGA)來驗證專門應用的集成電路(ASIC),專用標準產(chǎn)品(ASSP)和片上系統(tǒng)(SoC)的功能和性能。FPGA和ASIC前端代碼都是基于 Verilog HDL 開發(fā)的,所以ASIC代碼理論上是可以在FPGA平臺上跑起來的,在流片之前,盡可能的去確定芯片功能的正確性的一種驗證方式。
在我司,F(xiàn)PGA原型驗證的任務,交由驅動部門執(zhí)行,通常芯片設計部門的小伙伴會給我們出攜帶各種IP功能的”bit文件“,F(xiàn)PGA平臺(HAPS 80)有一個附帶的燒錄軟件,為了讓FPGA平臺變成目標SoC的”樣子“,需要使用這個燒錄軟件將bit文件燒錄到FPGA上。
SoC形成之后,我們會使用Arm的DS-5 IDE構建一個Bare Metal(裸機,不帶操作系統(tǒng))工程,編寫當前驗證SoC的初始化代碼,各個IP的驅動代碼,各個IP的測試demo,以及多個IP之間共同工作時的方案性的demo。主要目的是覆蓋測試SoC在實際運行時可能遇到的情況。
完成SoC本身的驗證之后,還會進行Bootrom的開發(fā),同樣也是在FPGA環(huán)境上進行驗證,這個環(huán)節(jié)非常關鍵,bootrom是芯片開始運行的起點,后期bringup是否可以成功,芯片的所用功能,性能,是否能夠有機會綻放出來,都得看bootrom的表現(xiàn)。有些企業(yè)會自己設計Bootrom的代碼,也有些企業(yè)則會基于安全啟動的考慮,會去使用Arm推出的解決方案 -- ATF。
ARM TrustZone是ARM公司推出的SoC及CPU系統(tǒng)范圍的安全解決方案,具有基于硬件的安全功能。它通過對原有硬件架構進行修改,在處理器層次引入了兩個不同權限的保護域——安全世界和普通世界,任何時刻處理器僅在其中的一個環(huán)境內(nèi)運行。
同時這兩個世界完全是硬件隔離的,并具有不同的權限,正常世界中運行的應用程序或操作系統(tǒng)訪問安全世界的資源受到嚴格的限制,反過來安全世界中運行的程序可以正常訪問正常世界中的資源。ATF將啟動過程分為三個階段:
Boot Loader stage 1 (BL1) AP Trusted ROM: 用于實現(xiàn)bootrom
Boot Loader stage 2 (BL2) Trusted Boot Firmware,二級loader
Boot Loader stage 3-1 (BL31) EL3 Runtime Software, 提供PSCI(電源管理等)、secure和nosecure切換等運行時服務
Boot Loader stage 3-2 (BL32) Secure-EL1 Payload (optional), 第三方的secure OS,如TEE等
Boot Loader stage 3-3 (BL33) Non-trusted Firmware,一般是uboot
其中,二級loader中常常會執(zhí)行DDR的初始化,將該階段獨立出來是非常有必要的,因為一顆SoC使用的DDR顆粒并不是永久一致的,如果將DDR初始化部分的代碼整合進BOOT階段,那么這顆SoC就不能使用其他的DDR。
驅動工程師在此的工作有許多,其中一部分為:
為基礎的部件,如GPIO,Pinctrl,Clock,Reset等模塊編寫驅動。
將ATF的IO存儲抽象層中的存儲介質相關的接口,適配為自家SoC上存儲介質的驅動。啟動方式有很多,如耳熟能詳?shù)?,spi-nor,spi-nand,uart?;蛘遝mmc,sd card,xip啟動等,通過Boot select的撥碼開關去選擇不同的啟動方式。
適配DDR。
實現(xiàn)熱啟動warm reset(直接從ATF階段跳轉到內(nèi)核運行),各家SoC的warm reset實現(xiàn)手段不同,依托的硬件機制不同。
實現(xiàn)多分區(qū)啟動等容災手段
基于ATF提供的工具,實現(xiàn)安全啟動,對rom的鏡像進行加密。
and soon...
這個階段的工作十分精密,需付出很多精力在FPGA平臺上,仔細驗證啟動功能,定時發(fā)送新的bootrom版本給到SoC驗證部門,在他們的環(huán)境上進行邏輯時序的仿真,SoC的驗證更加精細,在時序層面上可以分析出C程序對機器的每次操作,甚至是一次寄存器的讀寫,都可以進行捕捉。
SoC驗證也會對我們給出的bootrom程序進行性能上的分析,建立benchmark。兩個部門的交互在此階段非常頻繁(所以一定要和SoC部門的人打好關系,在他們的層面上去理解硬件,對于我們的幫助會更大)
在Bootrom的驗證成功之后,就會將文件發(fā)到代工廠進行流片。利用流片的這個時間空隙,驅動部門會進行SDK的回片前的預開發(fā)。
原廠給出的SDK通常包括uboot,kernel,prebuilts,libs,apps以及build。其中驅動部門所要負責的是uboot,build,prebuilts,以及最重要的kernel。(應用開發(fā)部門主要負責libs以及apps,驅動開發(fā)也會涉及一些libs目錄的責任,比如一些不對外開放的驅動源碼,會放在libs目錄,編譯后就會刪除)
build目錄主要是一些編譯腳本,SDK支持的開發(fā)板非常多,支持一鍵切換編譯出不同的開發(fā)板的鏡像,構建根文件系統(tǒng),lib,并進行打包。
由于一些歷史原因,uboot中各個層次之間組織架構,和linux ?kernel的組織非常類似,都是board—>machine—>arch—>cpu這樣的框架:
為了移植性,更容易地跨平臺運行,它倆的架構逐漸變成了上圖這個樣子。這張圖(來自蝸窩科技)揭示了uboot和kernel對于多種CPU,多種體系結構,多種機器類型,以及多種板級的抽象層次。我粗淺地認為,做嵌入式很難的一部分也正是在此(除開算法部分):
軟件工程中的抽象和封裝,力求以最簡潔、最高效的方式,實現(xiàn)盡可能多的功能,通過軟件抽象來掩蓋硬件的差異。這一點上,uboot和kernel的結構做得非常優(yōu)雅。
SDK的回片前的預開發(fā)也就是在這里CPU,Arch,Mach,Board四層次移植,適配目標SoC的代碼以及配置,各個模塊的驅動移植與開發(fā)(uboot也是需要開發(fā)驅動的),以uboot為例:
CPU層次,如ARMv8的初始化代碼,在ARM體系結構這個層次上對SoC進行初始化,比如MMU的配置,Cache的配置,大小端,異常等級的設置,通用定時器配置等
Arch層次,如arm的公共代碼,為后期執(zhí)行板級的配置(board_init_f/r),初始化執(zhí)行環(huán)境。
Machine層次,實則是一個通用的庫
Board層次,板級的特殊代碼,著名的board_init_f和board_init_r就會在此處實現(xiàn)。
如我前面所言,這個階段屬于預開發(fā)階段,所有的操作都在FPGA上運行,等到芯片實際流片回來,Bringup成功,就會將這段時間里的成果,遷移到實際的Evaluation board上去,以快速給到客戶實際的產(chǎn)品。
最后就來到SLT(system level test)了,這是芯片量產(chǎn)前的最后一個測試,可能也會由驅動部門負責,這一塊我了解的不多,驅動這邊主要在為每個驅動模塊編寫自動化測試軟件。SLT所用的測試板會做的非常的龐大,因為需要對所有模塊進行統(tǒng)一的測試,通常需要上位機的支持,給測試板下達測試指令,以自動化地測試芯片各個模塊是否正常。SLT是一種純粹通過運行和使用來完成的測試。
到此處為止,還都是硅前階段,即行業(yè)黑話Pre-silicon,指硅片實際流片出之前的所有步驟,原則上驗證人員需要將所有的Bug攔截在硅前階段。這個階段漫長且如履薄冰,必須小心翼翼,規(guī)格嚴格,功夫到家。相比而言,驅動工程師在這段時間內(nèi)也一般來說不會很繁忙。
第二個階段是硅后驗證階段(Post-Silicon),指的是在產(chǎn)品流片、發(fā)布以后查缺補漏的階段,這個階段對設計缺陷的修復成本將會變得非常高。
硅后階段,驅動部門所需負責的工作:
對流片后的芯片進行BringUp
遷移FPGA上預開發(fā)版本的各個庫到EVB版本,并在EVB板上實際調(diào)通
各個模塊的驅動調(diào)通并驗證,做性能測試
給每個驅動寫測試Demo
支持客戶的疑難雜癥,支持應用部門的疑問和需求,維護驅動等
相比硅前而言,硅后的工作節(jié)奏會變得非???,壓力也會更大,Bringup失敗怎么辦,如何避免ECO?后期發(fā)現(xiàn)有一些非必現(xiàn)的BUG又怎么辦?特別是第5點,這是一個長期的過程,對于每個原廠的驅動開發(fā)者而言,這是一條永遠存在的副本,每個人管理自己所負責的那些驅動(有些比較復雜的驅動,如ISP,VPE等,則單獨交給某幾個人去負責)。
客戶的問題會被相應地路由到各自的Task List上來。內(nèi)核部分的異常屬于公共任務,由leader判定哪些開發(fā)者來解決(驅動開發(fā)者也需要非常理解linux內(nèi)核的工作機制)。一些大公司會有單獨的內(nèi)核部門解決內(nèi)核異常(如華為)。一般來說初創(chuàng)公司的SDK都會有很多問題。
比方說,有一次客戶反饋,我們的linux內(nèi)核,換了一個解壓算法后,性能表現(xiàn)特別差,約莫45s才能進到內(nèi)核初始化部分。經(jīng)過我進兩個月的定位與查找,發(fā)現(xiàn)是我們的uboot內(nèi)核中,沒有打開一個Errata項,Arm Core中有一個寄存器中的一個bit沒有配置上,該bit管理著Cache的表現(xiàn),如果這個bit不打開,即使Cache已經(jīng)使能了,也不會生效。后來我在海思的Patch列表中,也看到了這一點,看來各個IC公司都是一步步摸過來的。
04 、思考我們需要哪些?
上面簡單地敘述了一下一個驅動開發(fā)者在培育一顆芯片的過程中所付出的努力??偟膩碚f,原廠的驅動開發(fā)者,特別是小廠的開發(fā)者,確實需要負責很多事務。
但我想說,透過現(xiàn)象看本質,在這個開發(fā)鏈條中,無論是Bare Metal,Uboot,Kernel,都是在配置寄存器,驅動工程師也被戲稱為寄存器配置工程師,這一點也沒錯,驅動開發(fā)就是在看手冊,看懂手冊后去寫配置代碼,讓硬件按想要的方式運行。這個過程也就是Bare Metal級別的開發(fā)邏輯,MCU開發(fā)者或許很熟悉ST的標準庫,HAL庫,LL庫,這些也就是在配置寄存器的基礎上套了一層框架,方便開發(fā)者對于驅動代碼的使用。
對于Uboot和Kernel部分的驅動開發(fā),底層邏輯依然是如此,只不過uboot與kernel為了統(tǒng)一開發(fā)者的行為,方便開發(fā)者將驅動加入他們的代碼,制定了一系列規(guī)則與框架,只需看懂他們的規(guī)則,了解他們的框架是如何運行,即可將驅動插入到其中。
所以對于”驅動怎么學習“這個命題來說,我想先往底層去討論,向底層,即探索硬件的運行機制,最標準,不走彎路的做法就是去啃芯片手冊,這個過程初入手也許非常痛苦,茫茫手冊,動輒百千頁,如何去看?
無他,唯手熟爾。
有些同學可能過于依賴庫函數(shù)編程或者類似Cube IDE圖形化配置的這類模式,遇到一顆新的SoC就會覺得頭大。
其實手冊看多了也就習慣了,看著頁數(shù)很多,一大部分都是對寄存器的description,這部分當作字典查就好了,重要的是手冊頭部到中間那些東西。關于如何去看一份手冊,在宋寶華的《Linux設備驅動開發(fā)詳解》中有一些描述,可以作為參考:
寫好單一的模塊驅動,也許并不難,但如果將它與其他的模塊交互,與CPU的體系結構有一些關系呢?
在OSPI控制器的INDAC (Indirect Access Controller)模式下訪問時數(shù)據(jù)由SRAM中轉,Master通過AHB訪問讀寫SRAM中的數(shù)據(jù),這里SRAM的中轉地址的內(nèi)存屬性是否能夠隨意設置呢?
諸如這些問題也暗示驅動開發(fā)不能只見樹木,不見森林,需要適當?shù)厝W習整體的體系結構的知識,學習SoC各個部分的關系。這種需求在做電源域以及低功耗設計,ATF的BL31,uboot和kernel的啟動等部分時,都會有深刻的感覺。如果有機會去做虛擬化,安全加解密部分的工作,相信這種體驗會更加深刻。
向上探索,首先遇到的問題應該是“框架”,這是一個比較大的話題,對于uboot來說就是它的DM模型,對于Kernel或者RTOS來說,就是整個操作系統(tǒng)的原理和設備驅動程序機制這種驅動開發(fā)必須面對的問題,這一塊沒辦法展開多講,以書籍和視頻資源為輔,多看源碼,多調(diào)試,多去寫一些針對性的測試demo。
針對操作系統(tǒng),最近兩年我個人看得比較多的是南京大學的操作系統(tǒng)課程(所用教材是operating system-three easy pieces)以及MIT 6.S081(RISC-V架構)(我們電氣學院幾乎沒有開設針對OS的課程,如果想做Linux或者FreeBSD這類操作系統(tǒng)下的開發(fā),還是有必要學習一下的)。
這兩門課主要講解操作系統(tǒng)的理論知識,但其精髓還是在實驗課上,如果能夠吃透這兩門課的實驗課,進行魔改,寫到簡歷上也是個不錯的項目經(jīng)驗。
面對現(xiàn)代Linux這樣的操作系統(tǒng),直接去看它的源碼其實是非常吃力的,它在漫長的發(fā)展長河中進化出了很多”額外“的特性,如支持了一些調(diào)試手段,還有一些面對編譯器優(yōu)化的特性(如likely和unlikely),直接去看源碼會迷失在這些細節(jié)當中??梢韵葟腞TOS或者RVOS,LMOS,Xv6這樣的小型OS來入手研究。
在我看來,學習操作系統(tǒng)要面對的困難主要是兩點:
體系結構部分。這部分對于大多數(shù)驅動開發(fā)這里來說非常陌生,特別是只做BSP層以上的開發(fā)者(可以跳過對體系結構的理解)。操作系統(tǒng)是建立在硬件上的,其多數(shù)重要的機制都依賴于體系結構提供的支持。
對于同一功能如進程管理,主流的體系結構都是類似的。相對而言,RISC-V的難度比Arm的難度小很多,可以從RISC-V的手冊開始看,但是畢竟當前崗位數(shù)量上還是ARM多,我們也可以功利一些,直接入手ARM,舊版本如ARMv7可以看杜春雷的ARM體系結構與編程,MCU級別的可以看Cortex系列的權威指南,高版本如ARMv8以上可以看笨叔的《ARM64體系結構與編程》。
算法。如內(nèi)存管理方面的算法,SLAB,Buddy。進程調(diào)度方面的算法,CFS等。如果就業(yè)目標并不是專精內(nèi)核的方向,這一塊無需做多深入,將更多的精力放在設備驅動和體系結構上會更有性價比。
再向上走,可能就是一些”形而上學“的東西:軟件架構。這一點在上面談到linux ?kernel的組織時已經(jīng)談過一些。Linux kernel雖然是以C這樣的面向過程的語言去編寫,但也處處使用著面向對象的思想,了解一些軟件架構上的做法,如解耦,開閉,接口隔離等,有助于理解kernel中各個組件的代碼。
最后我想說,做嵌入式驅動,畢竟不是搞科研,而是工程學,切莫只研究理論而丟失實際操作,學習一些調(diào)試手段,多去調(diào)試幾個工程是必要的。(但其實我也不會多少調(diào)試手段,當然了,printk應該算是玩的很6...,GDB在調(diào)試內(nèi)核時用的并不多,這是一個非常強大的工具但是我沒有heavliy地用過,倒是仿真器用得不少)
05 、閑談,一些淺薄的經(jīng)驗
這兩年常有許多朋友向我吐槽當前的就業(yè)環(huán)境,如果將剛畢業(yè)的我放在這個環(huán)境下,我應該也沒有多少把握去拿到一個滿意的offer,所以我在此篇文章中所給出的建議只能說是我主觀上覺得有用,有意義的建議。
如果讓我回到基地再重新經(jīng)歷一遍,我還是會去參加各類比賽,利用課余時間多做一些自己感興趣的小玩意兒,本科階段畢竟不是在工程或科研上廝殺的時候,但環(huán)境總會逼著我們不斷前進。
嵌入式,不管是驅動還是應用開發(fā),不管是做MCU還是ARM Linux,不管身處哪個方向:芯片,醫(yī)療,電機控制,運動控制,AI,協(xié)議?;蚴巧衔粰C,都是需要不斷學習,不斷專研,才能做得長久的。這需要我們擁有一些對行業(yè)的熱愛以及一些敢想敢做的極客精神。
當然,在前行的過程中,應該時刻記得最重要的,還是自己身心的健康愉悅。我的leader也曾這樣和我說過:能做好這一行的,無非就是兩種人。
第一種,天生就適合干這一行,我們組有個小哥,當時芯片回來要做HDMI,全公司沒有人做過,交給他兩天后就將屏幕點亮了,這種可能就是骨骼驚奇。第二種,就是能夠坐得住的,不斷摸索,肯花時間。
最后我再將上面的一些tips羅列一下:
基礎知識(計算機四大件)一定要學好,計組,OS這些在原理層面上的基礎要打牢,網(wǎng)絡不做相關方向的工作的話可以放一放以后再學。
做驅動的朋友,芯片手冊要認真研究,遇到問題先找手冊。比如IIC延展這些問題其實在芯片手冊里也會提到,DMA的S-G模式在圖像數(shù)據(jù)搬運時的應用,諸如此類的很多知識在芯片手冊上都有,當然ARM的核心手冊(TRM)也得好好專研。
學會調(diào)試,多動手。
在項目中鍛煉自己通常是最快的。
兩句真言:Read The F**king Source Code/Read the Friendly Manual
06 、推薦學習資源
視頻:
韋東山的教程,不必多說了,祖師爺.
南京大學操作系統(tǒng):[操作系統(tǒng)概述 (為什么要學操作系統(tǒng)) 南京大學2022操作系統(tǒng)-蔣炎巖-P1]嗶哩嗶哩bilibili
MIT 6.S081:【操作系統(tǒng)工程】精譯【MIT 公開課 MIT6.S081】嗶哩嗶哩bilibili
計算機基礎課:南京大學 - 計算機系統(tǒng)基礎 袁春風(一)- 程序的表示、轉換與鏈接嗶哩嗶哩bilibili
一生一芯:[“一生一芯”概述 第六期“一生一芯”計劃 - P1]嗶哩嗶哩bilibili
中科大RVOS:https://www.bilibili.com/video/BV1Q5411w7z5/?spm_id_from=333.337.search-card.all.click
書籍:
C語言功底:
C prime Plus
C專家編程
C接口與實現(xiàn)
多看源碼,多動手寫代碼,多抄優(yōu)質的代碼
計算機體系結構:
計算機組成與設計-硬件軟件接口
深入理解計算機系統(tǒng)(CSAPP)
笨叔的《ARM64體系結構與編程》
操作系統(tǒng)部分
操作系統(tǒng)導論 operating system-three easy pieces
深度探索嵌入式操作系統(tǒng)(LMOS)
《Understanding the linux kernel 3edt》
《linux設計與實現(xiàn)》
編譯原理部分:程序員的自我修養(yǎng) - 編譯 裝載 鏈接
博客:
蝸窩科技的博客Linux內(nèi)核分析 - 蝸窩科技 (wowotech.net)
面向Linux驅動開發(fā):
linux設備驅動程序內(nèi)核機制 -- 陳學松
linux設備驅動開發(fā)詳解 -- 宋寶華
Mastering Linux Kernel Development -- ?Robert Love
面向實戰(zhàn):
韋東山的一些項目還挺不錯的
蝸窩科技的博客上有一個X-project項目,很貼近實際企業(yè)的開發(fā)模式與開發(fā)內(nèi)容
07 、最后
對于選擇參加工作的同學,找工作前可以利用寒暑假找一份實習。拿到offer后最好仔細甄別,做好背調(diào)。例如,對于那些面試難度與薪酬待遇不成正比的公司應保持謹慎。信息收集可以通過脈脈,看準,知乎這類軟件,也可以詢問身邊的學長學姐。
希望大家都能找到滿意的工作,身體健康,工作順利,學業(yè)進步。
最后,最近在做嵌入式就業(yè)零基礎入門手把手教學,有興趣的朋友加vx聊: