性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

國(guó)產(chǎn)32開(kāi)發(fā)過(guò)程中的bug

大家在開(kāi)發(fā)過(guò)程中遇到BUG?

真正的目的是給自己一個(gè)糾錯(cuò)記錄,最近老是忘事,遇到的bug,過(guò)幾天再次遇到,就會(huì)忘了之前如何處理,遂留筆記一篇,也給后面可能遇到該問(wèn)題的小伙伴一個(gè)借鑒。

問(wèn)題匯總:最近沒(méi)得更新,主要是我們搞到了一批芯片,之前的項(xiàng)目可以重新提上日程,于是保留了之前的開(kāi)發(fā)思路,在其他MCU平臺(tái)上進(jìn)行重新開(kāi)發(fā),遇到的問(wèn)題是一件接著一件。首先產(chǎn)品端最初是STM32F030,現(xiàn)在的情況大家都了解,這顆料肯定是無(wú)法再用了,雖然手里還有幾千片存貨,可能一周都堅(jiān)持不住,于是主控?fù)Q成了GD32E230F4,主頻更高,但是flash太小,我的代碼編譯之后會(huì)超出內(nèi)存空間,此為所遇問(wèn)題之一。我們有一個(gè)用于給產(chǎn)品配合的小玩意,一般一個(gè)客戶有幾個(gè)就行,小客戶一個(gè)便可。之前為了開(kāi)發(fā)快捷迅速,選擇了STM32F103作為主控,所有功能開(kāi)發(fā)完畢。

但是因?yàn)檫@個(gè)小玩意是免費(fèi)贈(zèng)送,而且現(xiàn)在STM32F103也買不到,這個(gè)問(wèn)題只有換芯片才能解決,于是換了GD32E230F4,同樣面臨代碼空間不夠的問(wèn)題,而且還附帶其他問(wèn)題,此為其二。還有一個(gè)是用STM32F030遇到發(fā)送數(shù)據(jù)也會(huì)進(jìn)入U(xiǎn)SART的空閑中斷,無(wú)論代碼如何處理。此為其三。

問(wèn)題詳情及解決之道:

問(wèn)題一:flash空間不足的問(wèn)題我算是解決了一半,只能算解決了問(wèn)題,而解決問(wèn)題后所帶來(lái)的其他問(wèn)題,本人暫時(shí)無(wú)法追蹤原因。因?yàn)橹癝TM32F030的flash足夠大,所以沒(méi)遇到這個(gè)問(wèn)題,在資源緊張的GD32E230中遇到了。但是在缺貨的情況下,能找到一顆供應(yīng)滿足的MCU實(shí)屬不易,想方設(shè)法也得用起來(lái)。在代碼編寫完之后遇到如下問(wèn)題:

我第一次遇到這種問(wèn)題,去搜索發(fā)現(xiàn)是代碼太大,無(wú)法燒錄進(jìn)MCU的FLASH。檢查發(fā)現(xiàn)code的確超出容量了。

于是借鑒網(wǎng)絡(luò)上的方法提高優(yōu)化等級(jí)。

 可以發(fā)現(xiàn)明顯變小,燒錄也沒(méi)問(wèn)題,但是代碼不正常運(yùn)行,沒(méi)有卡死在任何地方,但是確實(shí)功能異常,在debug后發(fā)現(xiàn)問(wèn)題出在SPI通信,我使用DMA+SPI0,發(fā)送一個(gè)數(shù)組給傳感器例如tx[3] = {0x01,0x02,0x03};然后接受數(shù)組可以正常接收到傳感器數(shù)據(jù)rx[3] = {0x01,0x02,0x03},將優(yōu)化等級(jí)提高到1,此時(shí)SPI收到的數(shù)據(jù)rx[3] = {0x03,0x01,0x02}。這就導(dǎo)致了我后面處理SPI數(shù)據(jù)的時(shí)候數(shù)據(jù)出錯(cuò)。于是我將發(fā)送的數(shù)據(jù)改為4個(gè),也就是多發(fā)一個(gè)字節(jié),此時(shí)接收到的數(shù)據(jù)是rx[4] = {0x00,0x01,0x02,0x03}。我在取數(shù)據(jù)的時(shí)候取后三個(gè)便可,這是一個(gè)治標(biāo)不治本的辦法,至今我沒(méi)找到解決之道。其實(shí)這個(gè)問(wèn)題的根源就是硬件IIC的驅(qū)動(dòng)太大了,我沒(méi)能簡(jiǎn)化掉。但是發(fā)現(xiàn)提高優(yōu)化等級(jí)可以將代碼空間壓縮,那FLASH不就有閑置空間了嗎?為何還要用外置EEPROM呢?于是舍棄外置EEPROM,更換片內(nèi)FLAH。因?yàn)橐豁?yè)flash足夠我用了,這里只寫一頁(yè),下面的代碼是參考官方例程自己簡(jiǎn)化的一個(gè)寫FLASH的驅(qū)動(dòng),灰常好用。

void fmc_program(uint8_t* p_buffer,uint32_t Start_Address,uint16_t number_of_byte)

{

        uint32_t u32data;//fmc解鎖

        fmc_unlock();

        fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);

    fmc_page_erase(ERASE_PAGE_START_ADDR);

        address = PROGRAM_ADDRESS;

        for(uint16_t i = 0;i<number_of_byte;i++)

        {        

                u32data = (uint32_t)p_buffer[i]; 

                fmc_word_program(address, u32data);

                address+= 4U;

                fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);

        }

        

        fmc_lock();        //fmc上鎖

}

GD的FLASH例程叫FMC,一開(kāi)始都沒(méi)找到,以為例程沒(méi)有。

過(guò)程很簡(jiǎn)單:

1.使用庫(kù)函數(shù)fmc_unlock();函數(shù)將FLAH解鎖,

2.使用庫(kù)函數(shù)清標(biāo)志位fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);

3.使用庫(kù)函數(shù)fmc_page_erase(ERASE_PAGE_START_ADDR);擦除一頁(yè),寫之前必須先擦除,而且一擦就是整頁(yè),這里我有個(gè)內(nèi)容沒(méi)寫,是需要先將原來(lái)的數(shù)據(jù)讀出來(lái)的,否則會(huì)造成不需要改的數(shù)據(jù)擦掉。讀數(shù)據(jù)直接取地址就行,將數(shù)據(jù)全讀到一個(gè)數(shù)組中,然后在數(shù)組中將需要改的數(shù)據(jù)修改,調(diào)用這個(gè)驅(qū)動(dòng)進(jìn)行寫便可。ERASE_PAGE_START_ADDR為該頁(yè)的首地址。4.調(diào)用函數(shù)fmc_word_program(address, u32data);循環(huán)寫入,我是從頁(yè)首開(kāi)始寫,這個(gè)參數(shù)address就是上面的ERASE_PAGE_START_ADDR。5.寫完重新置位標(biāo)志位并上鎖。

uint32_t data;

        address = PROGRAM_ADDRESS;

        for(uint16_t j=0;j<256;j++)//取出所有FLASH里面的數(shù)據(jù)

        {

                data = *(uint32_t*)address;

                i2c_rxbuff[j] = (uint8_t)data;        

                address += 4U; 

        }

上面是將整頁(yè)數(shù)據(jù)讀出放在數(shù)組i2c_rxbuff中。

這里忽然想到還有一個(gè)問(wèn)題,這里得說(shuō)一下:我的工程用到了IIC,目的是像24C04里面寫數(shù)據(jù),但是我的項(xiàng)目要求沒(méi)有足夠的時(shí)間給我寫,每個(gè)上位機(jī)的指令過(guò)來(lái)我必須及時(shí)回復(fù),間隔時(shí)間只有幾十微秒,而寫24c04需要的是ms級(jí)別的時(shí)間,而且GD32E230沒(méi)有足夠的DMA通道給我使用,會(huì)和URAT以及SPI的DMA沖突。于是擠壓了一點(diǎn)時(shí)間出來(lái),在主循環(huán)執(zhí)行IIC寫操作,其他應(yīng)用用DMA處理,這樣每個(gè)指令之間都可以空出一點(diǎn)點(diǎn)時(shí)間來(lái)寫,慢慢寫唄,不影響正常通信就行。但是在調(diào)試的時(shí)候發(fā)現(xiàn)了一個(gè)問(wèn)題,這個(gè)問(wèn)題很嚴(yán)重,但是不會(huì)影響我之前的應(yīng)用,前提是我不在主循環(huán)進(jìn)行IIC的讀寫。問(wèn)題很簡(jiǎn)單,我退出不了串口接收中斷,這個(gè)問(wèn)題在一般應(yīng)用中很常見(jiàn),但是因?yàn)轫?xiàng)目需求的原因,我所有的應(yīng)用都在中斷內(nèi)完成,沒(méi)有中斷外的應(yīng)用,都是一個(gè)中斷打斷另一個(gè)中斷。最后還是在論壇里找到了答案。這一點(diǎn)在GD的例程中是沒(méi)有體現(xiàn)的,

問(wèn)題二:代碼空間不足的問(wèn)題上文已經(jīng)處理,這里不贅述。這里說(shuō)一下其他問(wèn)題。我們的產(chǎn)品為例節(jié)省成本,基本都是使用MCU內(nèi)部時(shí)鐘,之前ST是,現(xiàn)在GD也是,所用外設(shè)為:USRAT,SPI,IIC。均無(wú)任何問(wèn)題。但是在芯片荒之前用STM32F103做這個(gè)小玩意時(shí)加上了外部晶振,而這次改用GD32E230再次取消外部晶振,于是遇到了大問(wèn)題。我通過(guò)定時(shí)器觸發(fā)SPI采集若干個(gè)數(shù)據(jù),在MCU內(nèi)部進(jìn)行算法處理,得到的值有問(wèn)題,我懷疑是MCU計(jì)算出錯(cuò),畢竟里面包括了浮點(diǎn)運(yùn)算,三角函數(shù)等等。于是我將數(shù)據(jù)導(dǎo)入到EXCLE中,發(fā)現(xiàn)計(jì)算并無(wú)問(wèn)題。最后問(wèn)題定位在定時(shí)器不準(zhǔn),在使用內(nèi)部時(shí)鐘時(shí),其他通信外設(shè)沒(méi)有問(wèn)題,我就覺(jué)得內(nèi)部時(shí)鐘是可靠的,但是遇到定時(shí)器他就歇菜了。于是重新打板,問(wèn)題得以解決。還有個(gè)問(wèn)題就是很容易出現(xiàn)的SPI通信問(wèn)題,在產(chǎn)品上,MCU和傳感器是在同一個(gè)PCB上,距離很近,用100Khz的通信速率可以讀寫傳感器內(nèi)部EEPROM,但是用這個(gè)小玩意和產(chǎn)品通信時(shí)通過(guò)排線連接,100K的通信速率會(huì)導(dǎo)致通信失敗,降低通信速率,將速率降低到50K便可。

問(wèn)題三:發(fā)送數(shù)據(jù)進(jìn)入串口接收中斷直到寫這篇帖子之前才找到原因,在網(wǎng)上沒(méi)找到這個(gè)問(wèn)題的解決之道,也懷疑過(guò)時(shí)清標(biāo)志位的問(wèn)題,但是無(wú)論我如何操作,都無(wú)法解決這個(gè)問(wèn)題。然后用示波器點(diǎn)了一下rx

明明在發(fā)送數(shù)據(jù),但是卻有一個(gè)下降沿,然后再看空閑中斷的定義:空閑中斷是接收數(shù)據(jù)后出現(xiàn)一個(gè)byte的高電平(空閑)狀態(tài),就會(huì)觸發(fā)空閑中斷.并不是空閑就會(huì)一直中斷,準(zhǔn)確的說(shuō)應(yīng)該是上升沿(停止位)后一個(gè)byte,如果一直是低電平是不會(huì)觸發(fā)空閑中斷的。因?yàn)檫@一個(gè)電平的下拉,導(dǎo)致電平回拉的時(shí)候產(chǎn)生了一個(gè)上升沿,導(dǎo)致誤判為空閑狀態(tài)。查看電路圖,發(fā)現(xiàn)了一顆礙事的下拉電阻。

于是將該電阻拆掉便可,這個(gè)問(wèn)題之所以一直未發(fā)現(xiàn),其實(shí)是之前所有的應(yīng)用都用不到空閑中斷,電路一直這么設(shè)計(jì)并無(wú)問(wèn)題,但是在空閑中斷應(yīng)用中就會(huì)導(dǎo)致出錯(cuò)。ps:硬件不是我設(shè)計(jì),所以這個(gè)問(wèn)題發(fā)現(xiàn)的比較晚,而且我之前發(fā)現(xiàn)這個(gè)問(wèn)題后在軟件上做處理給抵消了。不影響使用。

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請(qǐng)聯(lián)系:editor@netbroad.com
覺(jué)得內(nèi)容不錯(cuò)的朋友,別忘了一鍵三連哦!
贊 4
收藏 1
關(guān)注 211
成為作者 賺取收益
全部留言
0/200
  • Westbrook 2021-10-01 09:30
    選擇開(kāi)優(yōu)化需要在最開(kāi)始項(xiàng)目開(kāi)始的時(shí)候就要進(jìn)行設(shè)置,如果中途發(fā)現(xiàn)Flash容量不夠再去開(kāi)優(yōu)化等級(jí),很大程度代碼會(huì)運(yùn)行不正常,代碼往往不會(huì)按照你的邏輯去執(zhí)行了。
    回復(fù)