在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

STM32軟件層實現原理

科技綠洲 ? 來源:工程師進階筆記 ? 作者:工程師進階筆記 ? 2023-06-22 10:29 ? 次閱讀

一、前言

STM32為例,打開網絡上下載的例程或者是購買開發板自帶的例程,都會發現應用層中會有stm32f10x.h或者stm32f10x_gpio.h,這些文件嚴格來時屬于硬件層的,如果軟件層出現這些文件會顯得很亂。

使用過Linux的童鞋們肯定知道linux系統無法直接操作硬件層,打開linux或者rt_thread代碼會發現代碼中都會有device的源文件,沒錯,這就是驅動層。

圖片

二、實現原理

原理就是將硬件操作的接口全都放到驅動鏈表上,在驅動層實現device的open、read、write等操作。當然這樣做也有弊端,就是驅動find的時候需要遍歷一遍驅動鏈表,這樣會增加代碼運行時間。

三、代碼實現

國際慣例,寫代碼先寫頭文件。rt_thread中使用的是雙向鏈表,為了簡單在這我只用單向鏈表。有興趣的可以自行研究rt_thread

頭文件接口:

本次只實現如下接口,device_open 和device_close等剩下的接口可以自行研究。這樣就可以在應用層中只調用如下接口可實現:

/*
    驅動注冊
*/
int cola_device_register(cola_device_t *dev);
/*
    驅動查找
*/
cola_device_t *cola_device_find(const char *name);
/*
    驅動讀
*/
int cola_device_read(cola_device_t *dev,  int pos, void *buffer, int size);
/*
    驅動寫
*/
int cola_device_write(cola_device_t *dev, int pos, const void *buffer, int size);
/*
    驅動控制
*/
int cola_device_ctrl(cola_device_t *dev,  int cmd, void *arg);;

頭文件cola_device.h:

#ifndef _COLA_DEVICE_H_
#define _COLA_DEVICE_H_
 
 
enum LED_state
{
    LED_OFF,
    LED_ON,
    LED_TOGGLE,
 
};
 
typedef struct cola_device  cola_device_t;
 
struct cola_device_ops
{
    int  (*init)   (cola_device_t *dev);
    int  (*open)   (cola_device_t *dev, int oflag);
    int  (*close)  (cola_device_t *dev);
    int  (*read)   (cola_device_t *dev, int pos, void *buffer, int size);
    int  (*write)  (cola_device_t *dev, int pos, const void *buffer, int size);
    int  (*control)(cola_device_t *dev, int cmd, void *args);
 
};
 
struct cola_device
{
    const char * name;
    struct cola_device_ops *dops;
    struct cola_device *next;
};
 
/*
    驅動注冊
*/
int cola_device_register(cola_device_t *dev);
/*
    驅動查找
*/
cola_device_t *cola_device_find(const char *name);
/*
    驅動讀
*/
int cola_device_read(cola_device_t *dev,  int pos, void *buffer, int size);
/*
    驅動寫
*/
int cola_device_write(cola_device_t *dev, int pos, const void *buffer, int size);
/*
    驅動控制
*/
int cola_device_ctrl(cola_device_t *dev,  int cmd, void *arg);
 
#endif

源文件cola_device.c:

#include "cola_device.h"
#include < string.h >
#include < stdbool.h >
 
 
struct cola_device *device_list = NULL;
 
/*
    查找任務是否存在
*/
static bool cola_device_is_exists( cola_device_t *dev )
{
    cola_device_t* cur = device_list;
    while( cur != NULL )
    {
        if( strcmp(cur- >name,dev- >name)==0)
        {
            return true;
        }
        cur = cur- >next;
    }
    return false;
}
 
 
static int device_list_inster(cola_device_t *dev)
{
    cola_device_t *cur = device_list;
    if(NULL == device_list)
    {
        device_list = dev;
        dev- >next   = NULL;
    }
    else
    {
        while(NULL != cur- >next)
        {
            cur = cur- >next;
        }
        cur- >next = dev;
        dev- >next = NULL;
    }
    return 1;
}
 
/*
    驅動注冊
*/
int cola_device_register(cola_device_t *dev)
{
    if((NULL == dev) || (cola_device_is_exists(dev)))
    {
        return 0;
    }
 
    if((NULL == dev- >name) ||  (NULL == dev- >dops))
    {
        return 0;
    }
    return device_list_inster(dev);
 
}
/*
    驅動查找
*/
cola_device_t *cola_device_find(const char *name)
{
    cola_device_t* cur = device_list;
    while( cur != NULL )
    {
        if( strcmp(cur- >name,name)==0)
        {
            return cur;
        }
        cur = cur- >next;
    }
    return NULL;
}
/*
    驅動讀
*/
int cola_device_read(cola_device_t *dev,  int pos, void *buffer, int size)
{
    if(dev)
    {
        if(dev- >dops- >read)
        {
            return dev- >dops- >read(dev, pos, buffer, size);
        }
    }
    return 0;
}
/*
    驅動寫
*/
int cola_device_write(cola_device_t *dev, int pos, const void *buffer, int size)
{
    if(dev)
    {
        if(dev- >dops- >write)
        {
            return dev- >dops- >write(dev, pos, buffer, size);
        }
    }
    return 0;
}
/*
    驅動控制
*/
int cola_device_ctrl(cola_device_t *dev,  int cmd, void *arg)
{
    if(dev)
    {
        if(dev- >dops- >control)
        {
            return dev- >dops- >control(dev, cmd, arg);
        }
    }
    return 0;
}

硬件注冊方式:以LED為例,初始化接口void led_register(void),需要在初始化中調用。

#include "stm32f0xx.h"
#include "led.h"
#include "cola_device.h"
 
 
#define PORT_GREEN_LED                 GPIOC                   
#define PIN_GREENLED                   GPIO_Pin_13              
 
/* LED亮、滅、變化 */
#define LED_GREEN_OFF                  (PORT_GREEN_LED- >BSRR = PIN_GREENLED)
#define LED_GREEN_ON                   (PORT_GREEN_LED- >BRR  = PIN_GREENLED)
#define LED_GREEN_TOGGLE               (PORT_GREEN_LED- >ODR ^= PIN_GREENLED)
 
 
static cola_device_t led_dev;
 
static void led_gpio_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = PIN_GREENLED;                            
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                     
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                     
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;                  
    GPIO_Init(PORT_GREEN_LED, &GPIO_InitStructure);
    LED_GREEN_OFF;
}
 
static int led_ctrl(cola_device_t *dev, int cmd, void *args)
{
    if(LED_TOGGLE == cmd)
    {
        LED_GREEN_TOGGLE;
    }
    else 
    {
        
    }
    return 1;
}
 
 
static struct cola_device_ops ops =
{
    .control = led_ctrl,
};
 
void led_register(void)
{
    led_gpio_init();
    led_dev.dops = &ops;
    led_dev.name = "led";
    cola_device_register(&led_dev);
}

應用層app代碼:

#include < string.h >
#include "app.h"
#include "config.h"
#include "cola_device.h"
#include "cola_os.h"
 
static task_t timer_500ms;
static cola_device_t *app_led_dev;
 
//led每500ms狀態改變一次
static void timer_500ms_cb(uint32_t event)
{
    cola_device_ctrl(app_led_dev,LED_TOGGLE,0);
}
 
void app_init(void)
{
    app_led_dev = cola_device_find("led");
    assert(app_led_dev);
    cola_timer_create(&timer_500ms,timer_500ms_cb);
    cola_timer_start(&timer_500ms,TIMER_ALWAYS,500);
}

這樣app.c文件中就不需要調用led.h頭文件了,rtt就是這樣實現的。

四、總結

這樣就可以實現軟硬件分層了,是不是非常好用!

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • STM32
    +關注

    關注

    2290

    文章

    11018

    瀏覽量

    362715
  • 軟件
    +關注

    關注

    69

    文章

    5124

    瀏覽量

    88987
  • 代碼
    +關注

    關注

    30

    文章

    4891

    瀏覽量

    70310
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    STM32CubeIDE軟件實現STM32外部中斷實例

    本文用STM32CubeIDE軟件實現STM32外部中斷實例。
    的頭像 發表于 08-24 09:09 ?4805次閱讀

    STM32Cube硬件抽象

      STM32Cubemx是一個便捷,方便管理的軟件平臺。極大的優化了開發的過程,盡管很多人對此不適應。它包括了ST產品的每個系列除了STM8。平臺包括了STM32Cube硬件抽象(
    發表于 08-03 07:45

    STM32是怎樣去實現軟件時間片調度的

    STM32 實現軟件時間片調度前言:在有些時候嵌入式系統不需要上RTOS的情況下,使用一個while大循環,有可能會造成一while套一
    發表于 08-24 07:33

    AUTOSAR基礎軟件是由哪些部分組成的

    AUTOSAR基礎軟件即BSW(Basic Software),與應用、運行環境共同搭建了AUTOSAR的
    發表于 02-17 08:00

    stm32軟件如何驅動LCD?

    LCD的接口模式有哪些?stm32軟件如何驅動LCD?
    發表于 02-23 06:12

    stm32用什么軟件寫程序

    stm32用什么軟件寫程序?STM32單片機在編程時可以使用庫函數和使用配置寄存器的方式來進行程序的實現。
    發表于 09-21 16:00 ?1.5w次閱讀

    STM32軟件架構設計

    STM32軟件架構1、架構設計的意義(1)應用代碼邏輯清晰,且避免代碼冗余;(2)代碼通用性,方便軟件高速、有效的移植;(3)各功能獨立,低耦合高內聚;2、總體架構圖3、結構說明4、
    發表于 11-06 09:05 ?35次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>軟件</b>架構設計

    STM32軟件模擬串口的實現-基于CrubeMX

    STM32軟件模擬串口的實現-基于CrubeMX
    發表于 11-30 10:36 ?10次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>軟件</b>模擬串口的<b class='flag-5'>實現</b>-基于CrubeMX

    STM32CubeMX實戰教程(一)——軟件入門

    STM32Cube 是一個全面的軟件平臺,包括了ST產品的每個系列。平臺包括了STM32Cube 硬件抽象(一個STM32抽象
    發表于 12-07 17:36 ?2次下載
    <b class='flag-5'>STM32</b>CubeMX實戰教程(一)——<b class='flag-5'>軟件</b>入門

    STM32 硬件抽象(Hardware Abstraction la

    STM32 硬件抽象(Hardware Abstraction la
    發表于 12-09 12:06 ?1次下載
    <b class='flag-5'>STM32</b> 硬件抽象<b class='flag-5'>層</b>(Hardware Abstraction la

    AUTOSAR 基礎軟件

    AUTOSAR基礎軟件即BSW(Basic Software),與應用、運行環境共同搭建了AUTOSAR的
    發表于 12-22 19:03 ?26次下載
    AUTOSAR 基礎<b class='flag-5'>軟件</b><b class='flag-5'>層</b>

    一個通用嵌入式驅動的代碼實現

    STM32為例,打開網絡上下載的例程或者是購買開發板自帶的例程,都會發現應用中會有stm32f10x.h或者stm32f10x_gpio.h,這些文件嚴格來時屬于硬件
    的頭像 發表于 11-16 11:31 ?1076次閱讀

    AN4457_基于STM32F4xx系列單片機軟件模擬UART的設計實現

    AN4457_基于STM32F4xx系列單片機軟件模擬UART的設計實現
    發表于 11-21 08:11 ?0次下載
    AN4457_基于<b class='flag-5'>STM32</b>F4xx系列單片機<b class='flag-5'>軟件</b>模擬UART的設計<b class='flag-5'>實現</b>

    UM1725_STM32F4的HAL和LL用戶手冊

    UM1725_STM32F4的HAL和LL用戶手冊
    發表于 11-22 08:21 ?22次下載
    UM1725_<b class='flag-5'>STM32</b>F4的HAL<b class='flag-5'>層</b>和LL<b class='flag-5'>層</b>用戶手冊

    在嵌入式中如何實現應用和硬件分層管理呢

    STM32為例,打開網絡上下載的例程或者是購買開發板自帶的例程,都會發現應用中會有stm32f10x.h或者stm32f10x_gpio.h,這些文件嚴格來時屬于硬件
    發表于 06-14 17:55 ?879次閱讀
    在嵌入式中如何<b class='flag-5'>實現</b>應用<b class='flag-5'>層</b>和硬件<b class='flag-5'>層</b>分層管理呢
    主站蜘蛛池模板: 黄色短视频免费看 | 伊人久久大 | 天天舔天天射天天操 | 日韩毛片大全免费高清 | 国产亚洲自在精品久久 | 久久精品男人的天堂 | 深夜大尺度视频在线观看 | 久久国内| 婷婷综合久久狠狠色99h | 伊人亚洲综合网成人 | 色五月婷婷成人网 | 亚洲酒色1314狠狠做 | 一区二区三区四区在线观看视频 | 寄宿日记免费看 | 激情91| 激情福利 | 午夜免费剧场 | 永久免费影视在线观看 | 天天操夜夜添 | 国产天天射 | 伊人网网站 | 国产区亚洲区 | 久月婷婷 | 亚洲色图欧美在线 | 性欧美大战久久久久久久野外 | 午夜免费片在线观看不卡 | 欧美国产黄色 | 亚洲色图欧美色 | 亚洲免费在线观看 | 亚洲资源在线观看 | 一区二区不卡在线观看 | 天天操人人射 | 国产高清视频免费最新在线 | 国产在线观看网址你懂得 | 日韩艹 | 高黄网站| 日日噜噜夜夜狠狠tv视频免费 | 99久久综合给久久精品 | 亚洲成人在线网 | 日本免费黄色网 | 午夜性爽快 |