娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年12月14日(星期六)

2019年12月14日 | 基于Linux的kfifo移植到STM32(支持os的互斥訪問)

發布者:Huanle 來源: eefocus關鍵字:Linux  kfifo  移植  STM32  互斥訪問 手機看文章 掃描二維碼
隨時隨地手機看文章

關于kfifo

kfifo是內核里面的一個First In First Out數據結構,它采用環形循環隊列的數據結構來實現;它提供一個無邊界的字節流服務,最重要的一點是,它使用并行無鎖編程技術,即當它用于只有一個入隊線程和一個出隊線程的場情時,兩個線程可以并發操作,而不需要任何加鎖行為,就可以保證kfifo的線程安全。


具體什么是環形緩沖區,請看我以前的文章


說明

關于kfifo的相關概念我不會介紹,有興趣可以看他的相關文檔,我只將其實現過程移植重寫,移植到適用stm32開發板上,并且按照我個人習慣重新命名,RingBuff->意為環形緩沖區


RingBuff_t

環形緩沖區的結構體成員變量,具體含義看注釋。

buffer: 用于存放數據的緩存

size: buffer空間的大小

in, out: 和buffer一起構成一個循環隊列。 in指向buffer中隊頭,而且out指向buffer中的隊尾


typedef struct ringbuff 

{

uint8_t *buffer;  /* 數據區域 */

uint32_t size;      /* 環形緩沖區大小 */

uint32_t in;        /* 數據入隊指針 (in % size) */

uint32_t out;       /* 數據出隊指針 (out % size) */

#if USE_MUTEX

MUTEX_T *mutex;       /* 支持rtos的互斥 */

#endif

}RingBuff_t ;


Create_RingBuff

創建一個環形緩沖區,為了適應后續對緩沖區入隊出隊的高效操作,環形緩沖區的大小應為2^n字節,

如果不是這個大小,則系統默認裁剪以對應緩沖區字節。

當然還可以優化,不過我目前并未做,思路如下:如果系統支持動態分配內存,則向上對齊,避免浪費內存空間,否則就按照我默認的向下對齊,當內存越大,對齊導致內存泄漏則會越多。對齊采用的函數是roundup_pow_of_two。如果系統支持互斥量,那么還將創建一個互斥量用來做互斥訪問,防止多線程同時使用導致數據丟失。


/************************************************************

  * @brief   Create_RingBuff

  * @param   rb:環形緩沖區句柄

  *          buffer:環形緩沖區的數據區域

  *          size:環形緩沖區的大小,緩沖區大小要為2^n

  * @return  err_t:ERR_OK表示創建成功,其他表示失敗

  * @author  jiejie

  * @github  https://github.com/jiejieTop

  * @date    2018-xx-xx

  * @version v1.0

  * @note    用于創建一個環形緩沖區

  ***********************************************************/

err_t Create_RingBuff(RingBuff_t* rb, 

                      uint8_t *buffer,

                      uint32_t size

)

{

if((rb == NULL)||(buffer == NULL)||(size == 0))

{

PRINT_ERR("data is null!");

return ERR_NULL;

}

PRINT_DEBUG("ringbuff size is %d!",size);

/* 緩沖區大小必須為2^n字節,系統會強制轉換,

否則可能會導致指針訪問非法地址。

空間大小越大,強轉時丟失內存越多 */

if(size&(size - 1))

{

size = roundup_pow_of_two(size);

PRINT_DEBUG("change ringbuff size is %d!",size);

}


rb->buffer = buffer;

rb->size = size;

rb->in = rb->out = 0;

#if USE_MUTEX

  /* 創建信號量不成功 */

  if(!create_mutex(rb->mutex))

  {

    PRINT_ERR("create mutex fail!");

    ASSERT(ASSERT_ERR);

    return ERR_NOK;

  }

#endif

PRINT_DEBUG("create ringBuff ok!");

return ERR_OK;

}


roundup_pow_of_two

/************************************************************

  * @brief   roundup_pow_of_two

  * @param   size:傳遞進來的數據長度

  * @return  size:返回處理之后的數據長度

  * @author  jiejie

  * @github  https://github.com/jiejieTop

  * @date    2018-xx-xx

  * @version v1.0

  * @note    用于處理數據,使數據長度必須為 2^n

* 如果不是,則轉換,丟棄多余部分,如

* roundup_pow_of_two(66) -> 返回 64

  ***********************************************************/

static unsigned long roundup_pow_of_two(unsigned long x)

{

return (1 << (fls(x-1)-1)); //向下對齊

  //return (1UL << fls(x - 1)); //向上對齊,用動態內存可用使用

}


Delete_RingBuff

刪除一個環形緩沖區,刪除之后,緩沖區真正存儲地址是不會被改變的(目前我是使用自定義數組做緩沖區的),但是刪除之后,就無法對緩沖區進行讀寫操作。并且如果支持os的話,創建的互斥量會被刪除。


/************************************************************

  * @brief   Delete_RingBuff

  * @param   rb:環形緩沖區句柄

  * @return  err_t:ERR_OK表示成功,其他表示失敗

  * @author  jiejie

  * @github  https://github.com/jiejieTop

  * @date    2018-xx-xx

  * @version v1.0

  * @note    刪除一個環形緩沖區

  ***********************************************************/

err_t Delete_RingBuff(RingBuff_t *rb)

{

if(rb == NULL)

{

PRINT_ERR("ringbuff is null!");

return ERR_NULL;

}

rb->buffer = NULL;

rb->size = 0;

rb->in = rb->out = 0;

#if USE_MUTEX

  if(!deleta_mutex(rb->mutex))

  {

    PRINT_DEBUG("deleta mutex is fail!");

    return ERR_NOK;

  }

#endif

return ERR_OK;

}


Write_RingBuff

向環形緩沖區寫入指定數據,支持線程互斥訪問。用戶想要寫入緩沖區的數據長度不一定是真正入隊的長度,在完成的時候還要看看返回值是否與用戶需要的長度一致~

這個函數很有意思,也是比較高效的入隊操作,將指定區域的數據拷貝到指定的緩沖區中,過程看注釋即可


/************************************************************

  * @brief   Write_RingBuff

  * @param   rb:環形緩沖區句柄

  * @param   wbuff:寫入的數據起始地址

  * @param   len:寫入數據的長度(字節)

  * @return  len:實際寫入數據的長度(字節)

  * @author  jiejie

  * @github  https://github.com/jiejieTop

  * @date    2018-xx-xx

  * @version v1.0

  * @note    這個函數會從buff空間拷貝len字節長度的數據到

             rb環形緩沖區中的空閑空間。

  ***********************************************************/

uint32_t Write_RingBuff(RingBuff_t *rb,

                        uint8_t *wbuff, 

                        uint32_t len)

{

  uint32_t l;

#if USE_MUTEX

  /* 請求互斥量,成功才能進行ringbuff的訪問 */

  if(!request_mutex(rb->mutex))

  {

    PRINT_DEBUG("request mutex fail!");

    return 0;

  }

  else  /* 獲取互斥量成功 */

  {

#endif

    len = min(len, rb->size - rb->in + rb->out);


    /* 第一部分的拷貝:從環形緩沖區寫入數據直至緩沖區最后一個地址 */

    l = min(len, rb->size - (rb->in & (rb->size - 1)));

    memcpy(rb->buffer + (rb->in & (rb->size - 1)), wbuff, l);


    /* 如果溢出則在緩沖區頭寫入剩余的部分

       如果沒溢出這句代碼相當于無效 */

    memcpy(rb->buffer, wbuff + l, len - l);


    rb->in += len;

    

    PRINT_DEBUG("write ringBuff len is %d!",len);

#if USE_MUTEX

  }

  /* 釋放互斥量 */

  release_mutex(rb->mutex);

#endif

  return len;

}


Read_RingBuff

讀取緩沖區數據到指定區域,用戶指定讀取長度,用戶想要讀取的長度不一定是真正讀取的長度,在讀取完成的時候還要看看返回值是否與用戶需要的長度一致~也支持多線程互斥訪問。

也是緩沖區出隊的高效操作。過程看代碼注釋即可


/************************************************************

  * @brief   Read_RingBuff

  * @param   rb:環形緩沖區句柄

  * @param   wbuff:讀取數據保存的起始地址

  * @param   len:想要讀取數據的長度(字節)

  * @return  len:實際讀取數據的長度(字節)

  * @author  jiejie

  * @github  https://github.com/jiejieTop

  * @date    2018-xx-xx

  * @version v1.0

  * @note    這個函數會從rb環形緩沖區中的數據區域拷貝len字節

             長度的數據到rbuff空間。

  ***********************************************************/

uint32_t Read_RingBuff(RingBuff_t *rb,

                       uint8_t *rbuff, 

                       uint32_t len)

{

  uint32_t l;

#if USE_MUTEX

  /* 請求互斥量,成功才能進行ringbuff的訪問 */

  if(!request_mutex(rb->mutex))

  {

    PRINT_DEBUG("request mutex fail!");

    return 0;

  }

  else

  {

#endif

    len = min(len, rb->in - rb->out);


    /* 第一部分的拷貝:從環形緩沖區讀取數據直至緩沖區最后一個 */

    l = min(len, rb->size - (rb->out & (rb->size - 1)));

    memcpy(rbuff, rb->buffer + (rb->out & (rb->size - 1)), l);


    /* 如果溢出則在緩沖區頭讀取剩余的部分

       如果沒溢出這句代碼相當于無效 */

    memcpy(rbuff + l, rb->buffer, len - l);


    rb->out += len;

    

    PRINT_DEBUG("read ringBuff len is %d!",len);

#if USE_MUTEX

  }

  /* 釋放互斥量 */

  release_mutex(rb->mutex);

#endif

  return len;

}


獲取緩沖區信息

這些就比較簡單了,看看緩沖區可讀可寫的數據有多少


/************************************************************

  * @brief   CanRead_RingBuff

* @param   rb:環形緩沖區句柄

* @return  uint32:可讀數據長度 0 / len

  * @author  jiejie

  * @github  https://github.com/jiejieTop

  * @date    2018-xx-xx

  * @version v1.0

  * @note    可讀數據長度

  ***********************************************************/

uint32_t CanRead_RingBuff(RingBuff_t *rb)

{

if(NULL == rb)

{

PRINT_ERR("ringbuff is null!");

return 0;

}

if(rb->in == rb->out)

return 0;

if(rb->in > rb->out)

return (rb->in - rb->out);

return (rb->size - (rb->out - rb->in));

}


/************************************************************

  * @brief   CanRead_RingBuff

* @param   rb:環形緩沖區句柄

* @return  uint32:可寫數據長度 0 / len

  * @author  jiejie

  * @github  https://github.com/jiejieTop

  * @date    2018-xx-xx

  * @version v1.0

  * @note    可寫數據長度

  ***********************************************************/

uint32_t CanWrite_RingBuff(RingBuff_t *rb)

{

if(NULL == rb)

{

PRINT_ERR("ringbuff is null!");

return 0;

}


return (rb->size - CanRead_RingBuff(rb));

}


附帶

這里的代碼我是用于測試的,隨便寫的


RingBuff_t ringbuff_handle;

uint8_t rb[64];

uint8_t res[64];

Create_RingBuff(&ringbuff_handle, 

rb,

sizeof(rb));

Write_RingBuff(&ringbuff_handle,

                     res, 

                     datapack.data_length);

PRINT_DEBUG("CanRead_RingBuff = %d!",CanRead_RingBuff(&ringbuff_handle));

PRINT_DEBUG("CanWrite_RingBuff = %d!",CanWrite_RingBuff(&ringbuff_handle));

Read_RingBuff(&ringbuff_handle,

                     res, 

                     datapack.data_length);


支持多個os的互斥量操作

此處模仿了文件系統的互斥操作


#if USE_MUTEX

#define  MUTEX_TIMEOUT   1000     /* 超時時間 */

#define  MUTEX_T         mutex_t  /* 互斥量控制塊 */

#endif


/*********************************** mutex **************************************************/

[1] [2]
關鍵字:Linux  kfifo  移植  STM32  互斥訪問 引用地址:基于Linux的kfifo移植到STM32(支持os的互斥訪問)

上一篇:一種Cortex-M內核中的精確延時方法
下一篇:【干貨】老外的GitHub整理的stm32f4驅動庫

推薦閱讀

? ? ? ? 據ETnews給出的最新報道稱,蘋果正在為2019款的iPhone選擇新的屏幕,主要供應商還會是三星,不過是全新的OLED屏。  報道中提到,蘋果將在2019款iPhone中使用觸控式集成柔性OLED面板,這可以讓iPhone機身更纖薄,目前三星正在大力跟進這個技術。  從目前曝光的節奏看,三星這個新OLED屏技術名為“Y-OCTA”,技術最大的亮點是,將原有單...
前言早在 2010 年 1 月 27 日,就有一位非常偉大的思想家宣布了 PC(個人計算機)的死訊。十年后,盡管從 2010 年穿越至此的時光旅行者可能已經不認識它,但 PC 依然生機勃勃,依然非常活躍。毫無疑問,這就是這種“瀕危物種”的進化和生存方式。 正文 就在不久之前,還有相當一部分技術專家們確信,到 2020 年時,我們所知道、所使用、所熟悉...
無論是調整座椅至最佳位置還是能夠輕松打開行李箱,車身電子設備系統都可使用電機來提高駕乘人員的舒適性和便利性。金屬氧化物半導體場效應晶體管(MOSFET)控制這些應用的電動裝置。但將MOSFET用作開關給電子控制模塊設計(包括電磁干擾(EMI)和熱管理、電流感應、斷電制動以及診斷與保護)帶來了新的技術性挑戰。德州儀器開發的集成電路(IC)電機驅動...
  欣旺達電子股份有限公司(以下簡稱“公司”或“欣旺達”)于2021年12月13日召開第五屆董事會第二十一次會議、第五屆監事會第二十一次會議,審議通過了《關于子公司對外投資的議案》,同意欣旺達子公司欣旺達電動汽車電池有限公司(以下簡稱“欣旺達汽車電池”、“乙方”)在棗莊國家高新技術產業開發區成立項目公司(以下簡稱“項目公司”)負責建設“...

史海拾趣

問答坊 | AI 解惑

LTCC應用于大功率射頻電路的可能性研究

1引言   世界電子產品已進入一個速度更快、密度更高、體積更薄、成本更低且要求更有效散熱的封裝時代。隨著無線電通信領域(如手機)的迅速商業化,對降低成本,提高性能有很大的壓力。LTCC(低溫共燒陶瓷)技術是一種低成本封裝的解決方法,具有 ...…

查看全部問答∨

在CCS中能看到c轉換的匯編嗎?

在CMD里面可以看到匯編對應的偽指令,請問,如果我們寫的程序時C語言,那么我們能看到轉換后對應的匯編語言嗎?…

查看全部問答∨

安防行業真的步入3G時代了?

3G商用業務的展開,不僅僅是通信技術的革新應用,3G技術也成為了信息化建設中的又一亮點。作為一項全新的技術,它將更深層次地融入到社會應用中去,在安防領域它也同樣引領這時代的潮流。   過去信息化建設的重點更多地放在傳統互聯網上,隨著3 ...…

查看全部問答∨

LPC1343點亮LED

LED點亮了 這是下載的時候的界面…

查看全部問答∨

TCP層三次握手中的幾個問題?

問題一: 第一步、客戶端發一個SYN, 第二步、服務器回一個SYN+ACK, 第三步、客戶端發一個ACK, seq_no=07CC50EA,ack_no=78BEEA98 此時三次握手搞定。接下來開始傳送IP數據包了,但是我想請問下, 當第三步不成功的情況下,客戶端發了一個ACK,而 ...…

查看全部問答∨

如何讀取SD卡的序列號

用什么函數能讀取到SD卡的序列號呢?…

查看全部問答∨

cepc:x86疑問

牛牛們,我最近使用Windows ce 6.0 + Visual Studio 2005進行cepc:x86的開發,大家知道ce6.0現在不為x86集成了emulator,我選用DMA后在download device時就出現"Error: invalid or missing ROM or Image". 后面我按照MSDN上的說法做一個flooby ...…

查看全部問答∨

基于OMAP3517的量子相干態光通信接收機的設計

系統復雜,可能出現的情況比較多,我會盡量完成評估報告…

查看全部問答∨

地址和時序問題

用一個單片機stc89le52rc的p0口和cpld的8個i/o口相連,在尋址的時候為什么基地址從0xff00開始呢,cpld和單片機之間的數據傳輸是不是不虛言考慮時序啊?…

查看全部問答∨

Error: Flash Download failed - "Cortex-M3"

主芯片型號:STM32F103RET6 仿真器      :Jlink V8 Load "C:\\\\Users\\\\Administrator\\\\Desktop\\\\STM3210E-EVAL.axf" Set JLink Project File to "E:\\開發資料\\STM32\\STM32官網庫函數\\STM32F10x_StdPerip ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 定南县| 阳东县| 仲巴县| 宁国市| 红原县| 淳化县| 新邵县| 信阳市| 彭泽县| 五寨县| 上高县| 芷江| 外汇| 清苑县| 四子王旗| 进贤县| 西安市| 日照市| 黄浦区| 崇礼县| 长丰县| 海伦市| 枣庄市| 吴堡县| 鹤壁市| 香港 | 开阳县| 增城市| 龙陵县| 保山市| 白朗县| 临澧县| 宁南县| 三门峡市| 崇仁县| 东至县| 江达县| 南充市| 华亭县| 兴安县| 崇明县|