一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

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

3天內(nèi)不再提示

基于Linux的kfifo移植到STM32

汽車電子技術(shù) ? 來源:物聯(lián)網(wǎng)IoT開發(fā) ? 作者:杰杰 ? 2023-02-14 09:52 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

基于Linux的kfifo移植到STM32(支持os的互斥訪問)

關(guān)于kfifo

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

具體什么是環(huán)形緩沖區(qū),請看我以前的文章

說明

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

往期關(guān)于環(huán)形緩沖區(qū)的文章:

杰杰帶你解讀【機智云】環(huán)形緩沖區(qū)源碼

STM32進階之串口環(huán)形緩沖區(qū)實現(xiàn)

RingBuff_t

環(huán)形緩沖區(qū)的結(jié)構(gòu)體成員變量,具體含義看注釋。

buffer: 用于存放數(shù)據(jù)的緩存

size: buffer空間的大小

in, out: 和buffer一起構(gòu)成一個循環(huán)隊列。 in指向buffer中隊頭,而且out指向buffer中的隊尾

typedef struct ringbuff 
{
    uint8_t *buffer;    /* 數(shù)據(jù)區(qū)域 */
    uint32_t size;      /* 環(huán)形緩沖區(qū)大小 */
    uint32_t in;        /* 數(shù)據(jù)入隊指針 (in % size) */
    uint32_t out;       /* 數(shù)據(jù)出隊指針 (out % size) */
#if USE_MUTEX
    MUTEX_T *mutex;       /* 支持rtos的互斥 */
#endif
}RingBuff_t ;

Create_RingBuff

創(chuàng)建一個環(huán)形緩沖區(qū),為了適應(yīng)后續(xù)對緩沖區(qū)入隊出隊的高效操作,環(huán)形緩沖區(qū)的大小應(yīng)為2^n字節(jié),

如果不是這個大小,則系統(tǒng)默認裁剪以對應(yīng)緩沖區(qū)字節(jié)。

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

/************************************************************
  * @brief   Create_RingBuff
  * @param   rb:環(huán)形緩沖區(qū)句柄
  *          buffer:環(huán)形緩沖區(qū)的數(shù)據(jù)區(qū)域
  *          size:環(huán)形緩沖區(qū)的大小,緩沖區(qū)大小要為2^n
  * @return  err_t:ERR_OK表示創(chuàng)建成功,其他表示失敗
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    用于創(chuàng)建一個環(huán)形緩沖區(qū)
  ***********************************************************/
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);
    /* 緩沖區(qū)大小必須為2^n字節(jié),系統(tǒng)會強制轉(zhuǎn)換,
         否則可能會導(dǎo)致指針訪問非法地址。
         空間大小越大,強轉(zhuǎn)時丟失內(nèi)存越多 */
    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    
  /* 創(chuàng)建信號量不成功 */
  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:傳遞進來的數(shù)據(jù)長度
  * @return  size:返回處理之后的數(shù)據(jù)長度
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    用于處理數(shù)據(jù),使數(shù)據(jù)長度必須為 2^n
    *                    如果不是,則轉(zhuǎ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));            //向上對齊,用動態(tài)內(nèi)存可用使用
}

Delete_RingBuff

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

/************************************************************
  * @brief   Delete_RingBuff
  * @param   rb:環(huán)形緩沖區(qū)句柄
  * @return  err_t:ERR_OK表示成功,其他表示失敗
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    刪除一個環(huán)形緩沖區(qū)
  ***********************************************************/
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

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

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

/************************************************************
  * @brief   Write_RingBuff
  * @param   rb:環(huán)形緩沖區(qū)句柄
  * @param   wbuff:寫入的數(shù)據(jù)起始地址
  * @param   len:寫入數(shù)據(jù)的長度(字節(jié))
  * @return  len:實際寫入數(shù)據(jù)的長度(字節(jié))
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    這個函數(shù)會從buff空間拷貝len字節(jié)長度的數(shù)據(jù)到
             rb環(huán)形緩沖區(qū)中的空閑空間。
  ***********************************************************/
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);

    /* 第一部分的拷貝:從環(huán)形緩沖區(qū)寫入數(shù)據(jù)直至緩沖區(qū)最后一個地址 */
    l = min(len, rb->size - (rb->in & (rb->size - 1)));
    memcpy(rb->buffer + (rb->in & (rb->size - 1)), wbuff, l);

    /* 如果溢出則在緩沖區(qū)頭寫入剩余的部分
       如果沒溢出這句代碼相當于無效 */
    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

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

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

/************************************************************
  * @brief   Read_RingBuff
  * @param   rb:環(huán)形緩沖區(qū)句柄
  * @param   wbuff:讀取數(shù)據(jù)保存的起始地址
  * @param   len:想要讀取數(shù)據(jù)的長度(字節(jié))
  * @return  len:實際讀取數(shù)據(jù)的長度(字節(jié))
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    這個函數(shù)會從rb環(huán)形緩沖區(qū)中的數(shù)據(jù)區(qū)域拷貝len字節(jié)
             長度的數(shù)據(jù)到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);

    /* 第一部分的拷貝:從環(huán)形緩沖區(qū)讀取數(shù)據(jù)直至緩沖區(qū)最后一個 */
    l = min(len, rb->size - (rb->out & (rb->size - 1)));
    memcpy(rbuff, rb->buffer + (rb->out & (rb->size - 1)), l);

    /* 如果溢出則在緩沖區(qū)頭讀取剩余的部分
       如果沒溢出這句代碼相當于無效 */
    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;
}

獲取緩沖區(qū)信息

這些就比較簡單了,看看緩沖區(qū)可讀可寫的數(shù)據(jù)有多少

/************************************************************
  * @brief   CanRead_RingBuff
    * @param   rb:環(huán)形緩沖區(qū)句柄
    * @return  uint32:可讀數(shù)據(jù)長度 0 / len
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    可讀數(shù)據(jù)長度
  ***********************************************************/
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:環(huán)形緩沖區(qū)句柄
    * @return  uint32:可寫數(shù)據(jù)長度 0 / len
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    可寫數(shù)據(jù)長度
  ***********************************************************/
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的互斥量操作

此處模仿了文件系統(tǒng)的互斥操作

#if USE_MUTEX
#define  MUTEX_TIMEOUT   1000     /* 超時時間 */
#define  MUTEX_T         mutex_t  /* 互斥量控制塊 */
#endif

/*********************************** mutex **************************************************/
#if USE_MUTEX
/************************************************************
  * @brief   create_mutex
  * @param   mutex:創(chuàng)建信號量句柄
  * @return  創(chuàng)建成功為1,0為不成功。
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    創(chuàng)建一個互斥量,用戶在os中互斥使用ringbuff,
  *          支持的os有rtt、win32、ucos、FreeRTOSLiteOS
  ***********************************************************/
static err_t create_mutex(MUTEX_T *mutex)
{
  err_t ret = 0;

//    *mutex = rt_mutex_create("test_mux",RT_IPC_FLAG_PRIO); /* rtt */
//    ret = (err_t)(*mutex != RT_NULL);

//    *mutex = CreateMutex(NULL, FALSE, NULL);        /* Win32 */
//    ret = (err_t)(*mutex != INVALID_HANDLE_VALUE);

//    *mutex = OSMutexCreate(0, &err);        /* uC/OS-II */
//    ret = (err_t)(err == OS_NO_ERR);

//    *mutex = xSemaphoreCreateMutex();   /* FreeRTOS */
//    ret = (err_t)(*mutex != NULL);

//  ret = LOS_MuxCreate(&mutex);  /* LiteOS */
//    ret = (err_t)(ret != LOS_OK);
  return ret;
}
/************************************************************
  * @brief   deleta_mutex
  * @param   mutex:互斥量句柄
  * @return  NULL
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    刪除一個互斥量,支持的os有rtt、win32、ucos、FreeRTOS、LiteOS
  ***********************************************************/
static err_t deleta_mutex(MUTEX_T *mutex)
{
    err_t ret;

//    ret = rt_mutex_delete(mutex);   /* rtt */

//    ret = CloseHandle(mutex);   /* Win32 */

//    OSMutexDel(mutex, OS_DEL_ALWAYS, &err); /* uC/OS-II */
//    ret = (err_t)(err == OS_NO_ERR);

//  vSemaphoreDelete(mutex);        /* FreeRTOS */
//    ret = 1;

//  ret = LOS_MuxDelete(&mutex);  /* LiteOS */
//    ret = (err_t)(ret != LOS_OK);

    return ret;
}
/************************************************************
  * @brief   request_mutex
  * @param   mutex:互斥量句柄
  * @return  NULL
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    請求一個互斥量,得到互斥量的線程才允許進行訪問緩沖區(qū)
  *          支持的os有rtt、win32、ucos、FreeRTOS、LiteOS
  ***********************************************************/
static err_t request_mutex(MUTEX_T *mutex)
{
    err_t ret;

//    ret = (err_t)(rt_mutex_take(mutex, MUTEX_TIMEOUT) == RT_EOK);/* rtt */

//    ret = (err_t)(WaitForSingleObject(mutex, MUTEX_TIMEOUT) == WAIT_OBJECT_0);  /* Win32 */

//    OSMutexPend(mutex, MUTEX_TIMEOUT, &err));       /* uC/OS-II */
//    ret = (err_t)(err == OS_NO_ERR);

//    ret = (err_t)(xSemaphoreTake(mutex, MUTEX_TIMEOUT) == pdTRUE);  /* FreeRTOS */

//  ret = (err_t)(LOS_MuxPend(mutex,MUTEX_TIMEOUT) == LOS_OK);          /* LiteOS */

    return ret;
}
/************************************************************
  * @brief   release_mutex
  * @param   mutex:互斥量句柄
  * @return  NULL
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    釋放互斥量,當線程使用完資源必須釋放互斥量
  *          支持的os有rtt、win32、ucos、FreeRTOS、LiteOS
  ***********************************************************/
static void release_mutex(MUTEX_T *mutex)
{
//    rt_mutex_release(mutex);/* rtt */

//    ReleaseMutex(mutex);        /* Win32 */

//    OSMutexPost(mutex);     /* uC/OS-II */

//    xSemaphoreGive(mutex);  /* FreeRTOS */

//  LOS_MuxPost(mutex);   /* LiteOS */
}
#endif
/*********************************** mutex **************************************************/

debug.h

最后送一份debug的簡便操作源碼,因為前文很多時候會調(diào)用

PRINT_ERR

PRINT_DEBUG

#ifndef _DEBUG_H
#define _DEBUG_H
/************************************************************
  * @brief   debug.h
  * @author  jiejie
  * @github  https://github.com/jiejieTop
  * @date    2018-xx-xx
  * @version v1.0
  * @note    此文件用于打印日志信息
  ***********************************************************/
/**
* @name Debug print 
* @{
*/
#define PRINT_DEBUG_ENABLE        1       /* 打印調(diào)試信息 */
#define PRINT_ERR_ENABLE            1   /* 打印錯誤信息 */
#define PRINT_INFO_ENABLE            0       /* 打印個人信息 */


#if PRINT_DEBUG_ENABLE
#define PRINT_DEBUG(fmt, args...)      do{(printf("\\n[DEBUG] >> "), printf(fmt, ##args));}while(0)     
#else
#define PRINT_DEBUG(fmt, args...)         
#endif

#if PRINT_ERR_ENABLE
#define PRINT_ERR(fmt, args...)      do{(printf("\\n[ERR] >> "), printf(fmt, ##args));}while(0)     
#else
#define PRINT_ERR(fmt, args...)           
#endif

#if PRINT_INFO_ENABLE
#define PRINT_INFO(fmt, args...)      do{(printf("\\n[INFO] >> "), printf(fmt, ##args));}while(0)     
#else
#define PRINT_INFO(fmt, args...)           
#endif

/**@} */

//針對不同的編譯器調(diào)用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
    #include 
#endif

/* 斷言 Assert */
#define AssertCalled(char,int)     printf("\\nError:%s,%d\\r\\n",char,int)
#define ASSERT(x)   if((x)==0)  AssertCalled(__FILE__,__LINE__)

typedef enum 
{
    ASSERT_ERR = 0,                             /* 錯誤 */
    ASSERT_SUCCESS = !ASSERT_ERR    /* 正確 */
} Assert_ErrorStatus;

typedef enum 
{
    FALSE = 0,      /* 假 */
    TRUE = !FALSE   /* 真 */
}ResultStatus;

#endif /* __DEBUG_H */
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    Linux系統(tǒng)移植開發(fā)篇2:燒寫linux鏡像

    本文章為《STM32MP157 Linux系統(tǒng)移植開發(fā)篇》系列中的一篇,筆者使用的開發(fā)平臺為華清遠見FS-MP1A開發(fā)板(STM32MP157開發(fā)板)。
    發(fā)表于 09-29 16:00 ?3469次閱讀
    <b class='flag-5'>Linux</b>系統(tǒng)<b class='flag-5'>移植</b>開發(fā)篇2:燒寫<b class='flag-5'>linux</b>鏡像

    stm32移植linux方法

    stm32移植linux方法,推薦分享一個朋友的人工智能教程,零基礎(chǔ)!通俗易懂!希望你也加入人工智能的隊伍中來!Ⅰ、概述該文寫針對初學(xué)μC/OS的朋友,基于以下平臺來一步一步
    發(fā)表于 08-09 09:17

    移植Linux晶心平臺

    鑒于越來越多使用者將Linux移植晶心平臺(Andes Embedded)上(AndesCore N12或N10),本文的目的在協(xié)助使用者快速、有效率的將Linux
    發(fā)表于 04-11 10:10 ?1029次閱讀
    <b class='flag-5'>移植</b><b class='flag-5'>Linux</b><b class='flag-5'>到</b>晶心平臺

    如何將SQLite移植linux的方法程序說明概述

    本文檔的主要內(nèi)容詳細介紹的是如何將SQLite移植linux的方法程序說明概述
    發(fā)表于 07-20 08:00 ?0次下載

    實操經(jīng)驗分享——在STM32移植Linux

    剛從硬件跳槽為嵌軟時,沒有任何一絲的準備。一入職,領(lǐng)導(dǎo)就交代了一項特難的任務(wù)——在stm32移植linux!
    的頭像 發(fā)表于 09-17 17:01 ?1.3w次閱讀

    GD32移植STM32開發(fā)平臺

    GD32移植STM32開發(fā)平臺
    發(fā)表于 12-02 14:51 ?28次下載
    GD32<b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>STM32</b>開發(fā)平臺

    RT-Thread系統(tǒng)移植STM32f103

    RT-Thread系統(tǒng)移植STM32f103
    發(fā)表于 12-09 12:51 ?26次下載
    RT-Thread系統(tǒng)<b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>STM32</b>f103

    AN5293 STM32F7系列移植STM32H7系列

    AN5293 STM32F7系列移植STM32H7系列
    發(fā)表于 11-21 12:57 ?1次下載
    AN5293 <b class='flag-5'>STM32</b>F7系列<b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>STM32</b>H7系列

    AN5293 STM32F7系列移植STM32H7系列

    AN5293 STM32F7系列移植STM32H7系列
    發(fā)表于 11-21 17:06 ?1次下載
    AN5293 <b class='flag-5'>STM32</b>F7系列<b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>STM32</b>H7系列

    AN3422_從STM32F1移植STM32L1的應(yīng)用手冊

    AN3422_從STM32F1移植STM32L1的應(yīng)用手冊
    發(fā)表于 11-21 17:06 ?4次下載
    AN3422_從<b class='flag-5'>STM32</b>F1<b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>STM32</b>L1的應(yīng)用手冊

    AN3427_從STM32F1移植STM32F2的應(yīng)用手冊

    AN3427_從STM32F1移植STM32F2的應(yīng)用手冊
    發(fā)表于 11-21 17:06 ?10次下載
    AN3427_從<b class='flag-5'>STM32</b>F1<b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>STM32</b>F2的應(yīng)用手冊

    AN4904_從STM32F1STM32F4的軟件移植

    AN4904_從STM32F1STM32F4的軟件移植
    發(fā)表于 11-21 17:06 ?5次下載
    AN4904_從<b class='flag-5'>STM32</b>F1<b class='flag-5'>到</b><b class='flag-5'>STM32</b>F4的軟件<b class='flag-5'>移植</b>

    AN4654_從STM32L1STM32L0的軟件移植

    AN4654_從STM32L1STM32L0的軟件移植
    發(fā)表于 11-21 17:06 ?1次下載
    AN4654_從<b class='flag-5'>STM32</b>L1<b class='flag-5'>到</b><b class='flag-5'>STM32</b>L0的軟件<b class='flag-5'>移植</b>

    AN4617_從STM32F0STM32L0的軟件移植

    AN4617_從STM32F0STM32L0的軟件移植
    發(fā)表于 11-21 17:06 ?5次下載
    AN4617_從<b class='flag-5'>STM32</b>F0<b class='flag-5'>到</b><b class='flag-5'>STM32</b>L0的軟件<b class='flag-5'>移植</b>

    Linux驅(qū)動移植 Linux系統(tǒng)架構(gòu)優(yōu)點

    系統(tǒng)移植 linux 驅(qū)動移植 移植是說同樣的一個 linux 操作系統(tǒng),我們可以跑到不同的硬件上面,我們把操作系統(tǒng)
    的頭像 發(fā)表于 07-27 17:06 ?1112次閱讀
    <b class='flag-5'>Linux</b>驅(qū)動<b class='flag-5'>移植</b> <b class='flag-5'>Linux</b>系統(tǒng)架構(gòu)優(yōu)點