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

歷史上的今天

今天是:2025年01月17日(星期五)

正在發生

2019年01月17日 | 2416開發記錄十:platform的相關函數詳解

發布者:qiuxubiao 來源: eefocus關鍵字:platform  相關函數 手機看文章 掃描二維碼
隨時隨地手機看文章

一、platform總線、設備與驅動


1.一個現實的Linux設備和驅動通常都需要掛接在一種總線上,對于本身依附于PCI、USB、I2C、SPI等的設備而言,這自然不是問題,


但是在嵌入式系統里面,SoC系統中集成的獨立的外設控制器、掛接在SoC內存空間的外設等確不依附于此類總線。


基于這一背景,Linux發明了一種虛擬的總線,稱為platform總線,相應的設備稱為platform_device,而驅動成為 platform_driver。


2.注意,所謂的platform_device并不是與字符設備、塊設備和網絡設備并列的概念,而是Linux系統提供的一種附加手段,


例如,在 S3C6410處理器中,把內部集成的I2C、RTC、SPI、LCD、看門狗等控制器都歸納為platform_device,而它們本身就是字符設備。



3.基于Platform總線的驅動開發流程如下:


(1)定義初始化platform bus

(2)定義各種platform devices

(3)注冊各種platform devices

(4)定義相關platform driver

(5)注冊相關platform driver

(6)操作相關設備


4.平臺相關結構


//platform_device結構體

    struct platform_device {

        const char * name;/* 設備名 */

        u32 id;//設備id,用于給插入給該總線并且具有相同name的設備編號,如果只有一個設備的話填-1。

        struct device dev;//結構體中內嵌的device結構體。

        u32 num_resources;/* 設備所使用各類資源數量 */

      struct resource * resource;/* //定義平臺設備的資源*/

    };


    //平臺資源結構

    struct resource {

        resource_size_t start; //定義資源的起始地址

        resource_size_t end; //定義資源的結束地址

        const char *name; //定義資源的名稱

        unsigned long flags; //定義資源的類型,比如MEM,IO,IRQ,DMA類型

        struct resource *parent, *sibling, *child;

    };


    //設備的驅動:platform_driver這個結構體中包含probe()、remove()、shutdown()、suspend()、 resume()函數,通常也需要由驅動實現。

    struct platform_driver {

        int (*probe)(struct platform_device *);

        int (*remove)(struct platform_device *);

        void (*shutdown)(struct platform_device *);

        int (*suspend)(struct platform_device *, pm_message_t state);

        int (*suspend_late)(struct platform_device *, pm_message_t state);

        int (*resume_early)(struct platform_device *);

        int (*resume)(struct platform_device *);

        struct pm_ext_ops *pm;

        struct device_driver driver;

    };


    //系統中為platform總線定義了一個bus_type的實例platform_bus_type,

    struct bus_type platform_bus_type = {

        .name = “platform”,

        .dev_attrs = platform_dev_attrs,

        .match = platform_match,

        .uevent = platform_uevent,

        .pm = PLATFORM_PM_OPS_PTR,

    };

    EXPORT_SYMBOL_GPL(platform_bus_type);


    //這里要重點關注其match()成員函數,正是此成員表明了platform_device和platform_driver之間如何匹配。

    static int platform_match(struct device *dev, struct device_driver *drv)

    {

        struct platform_device *pdev;


        pdev = container_of(dev, struct platform_device, dev);

        return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);

    }

    //匹配platform_device和platform_driver主要看二者的name字段是否相同。

    //對platform_device的定義通常在BSP的板文件中實現,在板文件中,將platform_device歸納為一個數組,最終通過platform_add_devices()函數統一注冊。

    //platform_add_devices()函數可以將平臺設備添加到系統中,這個函數的 原型為:

    int platform_add_devices(struct platform_device **devs, int num);

    //該函數的第一個參數為平臺設備數組的指針,第二個參數為平臺設備的數量,它內部調用了platform_device_register()函 數用于注冊單個的平臺設備。


1. platform bus總線先被kenrel注冊。


2. 系統初始化過程中調用platform_add_devices或者platform_device_register,將平臺設備(platform devices)注冊到平臺總線中(platform bus)


3. 平臺驅動(platform driver)與平臺設備(platform device)的關聯是在platform_driver_register或者driver_register中實現,一般這個函數在驅動的初始化過程調用。


通過這三步,就將平臺總線,設備,驅動關聯起來。


二.Platform初始化


系統啟動時初始化時創建了platform_bus總線設備和platform_bus_type總線,platform總線是在內核初始化的時候就注冊進了內核。


內核初始化函數kernel_init()中調用了do_basic_setup() ,該函數中調用driver_init(),該函數中調用platform_bus_init(),我們看看platform_bus_init()函數:


int __init platform_bus_init(void)

    {

           int error;

           early_platform_cleanup(); //清除platform設備鏈表

           //該函數把設備名為platform 的設備platform_bus注冊到系統中,其他的platform的設備都會以它為parent。它在sysfs中目錄下.即 /sys/devices/platform。

           //platform_bus總線也是設備,所以也要進行設備的注冊

           //struct device platform_bus = {

           //.init_name = "platform",

            //};

           error = device_register(&platform_bus);//將平臺bus作為一個設備注冊,出現在sys文件系統的device目錄

           if (error)

                  return error;

           //接著bus_register(&platform_bus_type)注冊了platform_bus_type總線.

           /*

           struct bus_type platform_bus_type = {

                        .name = “platform”,

                        .dev_attrs = platform_dev_attrs,

                        .match = platform_match,

                        .uevent = platform_uevent,

                        .pm = PLATFORM_PM_OPS_PTR,

                    };

           */

           //默認platform_bus_type中沒有定義probe函數。

           error = bus_register(&platform_bus_type);//注冊平臺類型的bus,將出現sys文件系統在bus目錄下,創建一個platform的目錄,以及相關屬性文件

           if (error)

                  device_unregister(&platform_bus);

           return error;

    }


    //總線類型match函數是在設備匹配驅動時調用,uevent函數在產生事件時調用。

    //platform_match函數在當屬于platform的設備或者驅動注冊到內核時就會調用,完成設備與驅動的匹配工作。

    static int platform_match(struct device *dev, struct device_driver *drv)

    {

           struct platform_device *pdev = to_platform_device(dev);

           struct platform_driver *pdrv = to_platform_driver(drv);

           /* match against the id table first */

           if (pdrv->id_table)

                  return platform_match_id(pdrv->id_table, pdev) != NULL;

           /* fall-back to driver name match */

           return (strcmp(pdev->name, drv->name) == 0);//比較設備和驅動的名稱是否一樣


    }


    static const struct platform_device_id *platform_match_id(struct platform_device_id *id,struct platform_device *pdev)

    {

           while (id->name[0]) {

                  if (strcmp(pdev->name, id->name) == 0) {

                         pdev->id_entry = id;

                         return id;

                  }

                  id++;

           }

           return NULL;


    }


    //不難看出,如果pdrv的id_table數組中包含了pdev->name,或者drv->name和pdev->name名字相同,都會認為是匹配成功。

    //id_table數組是為了應對那些對應設備和驅動的drv->name和pdev->name名字不同的情況。


    //再看看platform_uevent()函數:platform_uevent 熱插拔操作函數

    static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)

    {

           struct platform_device *pdev = to_platform_device(dev);

           add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, (pdev->id_entry) ? pdev->id_entry->name : pdev->name);

           return 0;

    }


    //添加了MODALIAS環境變量,我們回顧一下:platform_bus. parent->kobj->kset->uevent_ops為device_uevent_ops,bus_uevent_ops的定義如下:

    static struct kset_uevent_ops device_uevent_ops = {

           .filter = dev_uevent_filter,

           .name = dev_uevent_name,

           .uevent = dev_uevent,

    };

    //當調用device_add()時會調用kobject_uevent(&dev->kobj, KOBJ_ADD)產生一個事件,這個函數中會調用相應的kset_uevent_ops的uevent函數,


三.Platform設備的注冊


我們在設備模型的分析中知道了把設備添加到系統要調用device_initialize()和platform_device_add(pdev)函數。


Platform設備的注冊分兩種方式:


1.對于platform設備的初注冊,內核源碼提供了platform_device_add()函數,輸入參數platform_device可以是靜態的全局設備,它是進行一系列的操作后調用device_add()將設備注冊到相應的總線(platform總線)上,


內核代碼中platform設備的其他注冊函數都是基于這個函數,如platform_device_register()、platform_device_register_simple()、platform_device_register_data()等。


2.另外一種機制就是動態申請platform_device_alloc()一個platform_device設備,然后通過platform_device_add_resources及platform_device_add_data等添加相關資源和屬性。


無論哪一種platform_device,最終都將通過platform_device_add這冊到platform總線上。


區別在于第二步:其實platform_device_add()包括device_add(),不過要先注冊resources,然后將設備掛接到特定的platform總線。


第一種平臺設備注冊方式


    //platform_device是靜態的全局設備,即platform_device結構的成員已經初始化完成

    //直接將平臺設備注冊到platform總線上

    /*platform_device_register和device_register的區別:

   

 (1).主要是有沒有resource的區別,前者的結構體包含后面,并且增加了struct resource結構體成員,后者沒有。

 

           platform_device_register在device_register的基礎上增加了struct resource部分的注冊。


            由此。可以看出,platform_device---paltform_driver_register機制與device-driver的主要區別就在于resource。


            前者適合于具有獨立資源設備的描述,后者則不是。

   

 (2).其實linux的各種其他驅動機制的基礎都是device_driver。只不過是增加了部分功能,適合于不同的應用場合.

*/

    int platform_device_register(struct platform_device *pdev)

    {

        device_initialize(&pdev->dev);//初始化platform_device內嵌的device

        return platform_device_add(pdev);//把它注冊到platform_bus_type上

    }


    int platform_device_add(struct platform_device *pdev)

    {

            int i, ret = 0;

            if (!pdev)

             return -EINVAL;

            if (!pdev->dev.parent)

                pdev->dev.parent = &platform_bus;//設置父節點,即platform_bus作為總線設備的父節點,其余的platform設備都是它的子設備


            //platform_bus是一個設備,platform_bus_type才是真正的總線    

            pdev->dev.bus = &platform_bus_type;//設置platform總線,指定bus類型為platform_bus_type


            //設置pdev->dev內嵌的kobj的name字段,將platform下的名字傳到內部device,最終會傳到kobj

            if (pdev->id != -1)

             dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);

            else

             dev_set_name(&pdev->dev, "%s", pdev->name);



            //初始化資源并將資源分配給它,每個資源的它的parent不存在則根據flags域設置parent,flags為IORESOURCE_MEM,

            //則所表示的資源為I/O映射內存,flags為IORESOURCE_IO,則所表示的資源為I/O端口。

            for (i = 0; i < pdev->num_resources; i++) {

             struct resource *p, *r = &pdev->resource[i];

             if (r->name == NULL)//資源名稱為NULL則把設備名稱設置給它

                     r->name = dev_name(&pdev->dev);


             p = r->parent;//取得資源的父節點,資源在內核中也是層次安排的

             if (!p) {

             if (resource_type(r) == IORESOURCE_MEM) //如果父節點為NULL,并且資源類型為IORESOURCE_MEM,則把父節點設置為iomem_resource

                     p = &iomem_resource;

             else if (resource_type(r) == IORESOURCE_IO)//否則如果類型為IORESOURCE_IO,則把父節點設置為ioport_resource

                  p = &ioport_resource;

             }


             //從父節點申請資源,也就是出現在父節點目錄層次下

             if (p && insert_resource(p, r)) {

             printk(KERN_ERR "%s: failed to claim resource %d\n",dev_name(&pdev->dev), i);ret = -EBUSY;

             goto failed;

             }

            }


            pr_debug("Registering platform device '%s'. Parent at %s\n",dev_name(&pdev->dev), dev_name(pdev->dev.parent));

            //device_creat() 創建一個設備并注冊到內核驅動架構...

            //device_add() 注冊一個設備到內核,少了一個創建設備..

            ret = device_add(&pdev->dev);//就在這里把設備注冊到總線設備上,標準設備注冊,即在sys文件系統中添加目錄和各種屬性文件

            if (ret == 0)

             return ret;


            failed:

            while (--i >= 0) {

             struct resource *r = &pdev->resource[i];

             unsigned long type = resource_type(r);

             if (type == IORESOURCE_MEM || type == IORESOURCE_IO)

             release_resource(r);

            }

            return ret;


    }



4.第二種平臺設備注冊方式


//先分配一個platform_device結構,對其進行資源等的初始化

    //之后再對其進行注冊,再調用platform_device_register()函數

    struct platform_device * platform_device_alloc(const char *name, int id)

    {

        struct platform_object *pa;

        /*

        struct platform_object {

           struct platform_device pdev;

           char name[1];

        };

        */

        pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);//該函數首先為platform設備分配內存空間

        if (pa) {

            strcpy(pa->name, name);

            pa->pdev.name = pa->name;//初始化platform_device設備的名稱

            pa->pdev.id = id;//初始化platform_device設備的id

            device_initialize(&pa->pdev.dev);//初始化platform_device內嵌的device

            pa->pdev.dev.release = platform_device_release;

        }

        return pa ? &pa->pdev : NULL;

    }


    //一個更好的方法是,通過下面的函數platform_device_register_simple()動態創建一個設備,并把這個設備注冊到系統中:

    struct platform_device *platform_device_register_simple(const char *name,int id,struct resource *res,unsigned int num)

    {

           struct platform_device *pdev;

           int retval;

           pdev = platform_device_alloc(name, id);

           if (!pdev) {

                  retval = -ENOMEM;

                  goto error;

           }


           if (num) {

                  retval = platform_device_add_resources(pdev, res, num);

                  if (retval)

                         goto error;

           }


           retval = platform_device_add(pdev);

           if (retval)

                  goto error;


           return pdev;

    error:

           platform_device_put(pdev);

           return ERR_PTR(retval);

    }


    //該函數就是調用了platform_device_alloc()和platform_device_add()函數來創建的注冊platform device,函數也根據res參數分配資源,看看platform_device_add_resources()函數:

    int platform_device_add_resources(struct platform_device *pdev,struct resource *res, unsigned int num)

    {

           struct resource *r;

           r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL);//為資源分配內存空間

           if (r) {

                  memcpy(r, res, sizeof(struct resource) * num);

                  pdev->resource = r; //并拷貝參數res中的內容,鏈接到device并設置其num_resources

                  pdev-> num_resources = num;

           }

           return r ? 0 : -ENOMEM;

    }



四:設備資源


可以通過相關函數


struct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num)

//中斷資源也可以通過:

int platform_get_irq(struct platform_device *dev, unsigned int num) 


資源的使用主要是驅動實現過程中需要使用到的,但是后期的使用一般需要在驅動的probe函數中實現申請中斷或者IO內存才能使用,而不能直接使用。特別是資源中的地址通常是物理地址,需要通過申請IO內存和映射完成物理到虛擬地址的轉換,便于進程的訪問。


五.Platform設備驅動的注冊


我們在設備驅動模型的分析中已經知道驅動在注冊要調用driver_register(),

platform driver的注冊函數platform_driver_register()同樣也是進行其它的一些初始化后調用driver_register()將驅動注冊到platform_bus_type總線上.


int platform_driver_register(struct platform_driver *drv)

    {

           drv->driver.bus = &platform_bus_type;//它將要注冊到的總線

                /*設置成platform_bus_type這個很重要,因為driver和device是通過bus聯系在一起的,

                具體在本例中是通過 platform_bus_type中注冊的回調例程和屬性來是實現的,

                driver與device的匹配就是通過 platform_bus_type注冊的回調例程platform_match ()來完成的。

                */

           if (drv->probe)

                  drv-> driver.probe = platform_drv_probe;

           if (drv->remove)

                  drv->driver.remove = platform_drv_remove;

           if (drv->shutdown)

                  drv->driver.shutdown = platform_drv_shutdown;

           return driver_register(&drv->driver);//注冊驅動

    }


    //然后設定了platform_driver內嵌的driver的probe、remove、shutdown函數。

    static int platform_drv_probe(struct device *_dev)

    {

           struct platform_driver *drv = to_platform_driver(_dev->driver);

           struct platform_device *dev = to_platform_device(_dev);

           return drv->probe(dev);//調用platform_driver的probe()函數,這個函數一般由用戶自己實現

                                                           //例如下邊結構,回調的是serial8250_probe()函數

               /*

                    static struct platform_driver serial8250_isa_driver = {

                        .probe        = serial8250_probe,

                        .remove        = __devexit_p(serial8250_remove),

                        .suspend    = serial8250_suspend,

                        .resume        = serial8250_resume,

                        .driver        = {

                            .name    = "serial8250",

                            .owner    = THIS_MODULE,

                        },

                    };

                    */

    }


    static int platform_drv_remove(struct device *_dev)

    {

           struct platform_driver *drv = to_platform_driver(_dev->driver);

           struct platform_device *dev = to_platform_device(_dev);

           return drv->remove(dev);


    }


    static void platform_drv_shutdown(struct device *_dev)

    {

           struct platform_driver *drv = to_platform_driver(_dev->driver);

           struct platform_device *dev = to_platform_device(_dev);

           drv->shutdown(dev);


    }



六:簡單模板


實現的總線平臺驅動模型的最簡單源碼:


平臺設備的實現:device.c


#include

#include

#include

#include

#include

#include


/*平臺模型驅動的平臺設備對象*/

static struct platform_device *my_device;


/*初始化函數*/

static int __init my_device_init(void)

{

        int ret = 0;


        /*采用platform_device_alloc分配一個platform_device對象

          參數分別為platform_device的name,和id。

        */

        my_device = platform_device_alloc("my_dev",-1);


        /*注冊設備,注意不是platform_device_register,將平臺設備注冊到內核中*/

        ret = platform_device_add(my_device);


        /*如果出錯釋放相關的內存單元*/

        if(ret)

        {

                platform_device_put(my_device);

        }


        return ret;

}


/*卸載處理函數*/

static void __exit my_device_exit(void)


{

        platform_device_unregister(my_device);

}


module_init(my_device_init);

module_exit(my_device_exit);


MODULE_LICENSE("GPL");

MODULE_AUTHOR("GP-




平臺驅動的實現:driver.c


#include

#include

#include

#include

#include




/*平臺驅動中的probe和remove函數是必須實現的函數*/


/*設備驅動的探測函數,主要實現檢測總線上是否有該驅動對應的設備*/

static my_probe(struct device *dev)

{


        /*


           如果添加實際的設備到該平臺總線設備驅動模型中,則可以在該函數


           中實現具體的設備驅動函數的初始化操作,包括設備號的申請,設備


            的初始化,添加。自動設備文件創建函數的添加等操作。


            或者是混雜字符設備的相關初始化操作。當然結構體的相關處理仍


            然采取全局變量的形式。


        */

        printk("Driver found devices which this driver can be handle\n");

        return 0;

}


/*設備驅動的移除函數,主要檢測該驅動支持設備的移除活動檢測*/

static my_remove(struct device *dev)

{


        /*


            如果添加實際的設備到該平臺總線設備驅動模型中,則可以在該函數


            中實現具體的設備的釋放,包括設備的刪除,設備號的注銷等操作。


       */

        printk("Driver found device unpluded\n");

        return 0;

}


static struct platform_driver my_driver =

{

        /*平臺驅動的probe函數實現*/

        .probe = my_probe,

        /*平臺驅動的remove函數實現*/

        .remove = my_remove,

        /*實現設備驅動的name和owner變量*/

        .driver =

        {

                /*該參數主要實現總線中的匹配函數調用*/

                .name = "my_dev",

                /*該函數表示模塊的擁有者*/

                .owner = THIS_MODULE,

        },

};


/*初始化函數*/

static int __init my_driver_init(void)

{

        /*注冊平臺驅動*/

        return platform_driver_register(&my_driver);

}

/*退出函數*/

static void __exit my_driver_exit(void)

{

        /*注銷平臺驅動*/

        return platform_driver_unregister(&my_driver);

}


/*加載和卸載*/

module_init(my_driver_init);

module_exit(my_driver_exit);


MODULE_LICENSE("GPL");

MODULE_AUTHOR("GP-



//七:總結:


1.從這三個函數的代碼可以看到,又找到了相應的platform_driver和platform_device,然后調用platform_driver的probe、remove、shutdown函數。這是一種高明的做法:


在不針對某個驅動具體的probe、remove、shutdown指向的函數,而通過上三個過度函數來找到platform_driver,然后調用probe、remove、shutdown接口。


如果設備和驅動都注冊了,就可以通過bus ->match、bus->probe或driver->probe進行設備驅動匹配了。


2.驅動注冊的時候platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev(),

對每個掛在虛擬的platform bus的設備作__driver_attach()->driver_probe_device()->drv->bus->match()==platform_match()->比較strncmp(pdev->name, drv->name, BUS_ID_SIZE),

如果相符就調用platform_drv_probe()->driver->probe(),如果probe成功則綁定該設備到該驅動。


關鍵字:platform  相關函數 引用地址:2416開發記錄十:platform的相關函數詳解

上一篇:2416開發記錄九:實現設備節點的自動創建
下一篇:2416開發記錄十一:按鍵驅動(platform/中斷)

推薦閱讀

近日,有多家媒體報道稱阿里巴巴上線“挖礦平臺”并進入“虛擬貨幣”領域。騰訊也有類似傳聞。?日前,阿里云方面回應,表示該業務實際上是阿里云基于P2P技術的CDN(內容分發網絡)業務,與“挖礦平臺”、“虛擬貨幣”等毫無關聯。?最近一段時間,隨著比特幣,山寨幣的火熱,國內一些互聯網公司蠢蠢欲動,希望自己搞山寨幣來牟利,反正這個東西沒有什么成本...
方法一:為了保證在MDK中讀取正確的程序運行時間,必須對仿真器的跟蹤項進行設置。 以ULink2為例: (1)在工程的“ Option for Target ..”目標選項界面中,選擇標簽“Debug”,進行調試設置界面,選擇使用“Cortex-M3-ULIK2”作為仿真器,然后點擊右側的“Settings”按鍵,進入ULINK設置界面。 (2)點擊標簽“Trace”進入跟蹤設置界面,將“Core Cloc...
近日,在CES2020展會上,大疆內部孵化的子公司Livox發布兩款 專為自動駕駛汽車設計的激光雷達產品Horizon和Tele-15 。無獨有偶,英特爾子公司Mobileye演示了一輛自動駕駛汽車在12個車載攝像頭的幫助下,在耶路撒冷的街道上行駛了約20分鐘, 除了攝像頭以外,該自動駕駛系統沒有用到雷達、超聲波等其他傳感器。大疆發布的激光雷達產品和Mobileye發布的純...
ARM芯片中的片內和片外存儲器在芯片中的地址是由芯片廠家或用戶分配的.給物理存儲器分配邏輯地址的過程稱為存儲器映射.通過這些邏輯地址,就可以訪問到相應存儲器的物理存儲單元.我們再來看一下下面的lpc2300的物理地址的分布: 從上面圖中可以看出,AHB,APB兩個內存區域都是分配給外設使用了.每個外設空間大小為16KB,最多可以分配128個外設,總共各2MB左右...

史海拾趣

問答坊 | AI 解惑

[方案]某監獄閉路電視監控系統設計方案--5

4、彩色攝像機 VC-913D 技術規格: 圖像傳感器:1/3”SONY Super HAD CCD 有效像素:PAL:500(水平)*582(垂直)NTSC:510(水平)*492(垂直) 感光面積:4.9mm*3.7mm 信號系統:PAL/NTSC制式 水平清晰:420電視線 鏡頭安裝方式:C/CS ...…

查看全部問答∨

pxa270 系統flash只有nor 沒有nand怎么保存hive注冊表

我的系統的存儲設備只有nor cf卡和sd卡 想實現hive 可以在nor下實現嗎 我看到網上好多都是nand保持的 謝謝了…

查看全部問答∨

來拿分啊!!!呵呵

有沒有人有手機版的中國象棋,或者國際象棋代碼呀?不要JAVA開發的,要C++或者C#的.而且編譯要通過. 100分夠嗎?我就不到200了好象~…

查看全部問答∨

請問嵌入式開發的一般流程是什么?

菜鳥問題   我想請問一下,嵌入式開發從頭到尾的實際操作過程是什么樣的?比如都需要下載什么軟件,怎樣修改并裝載引導程序,怎樣移植操作系統,怎樣調試,怎樣燒寫.....   謝謝啦!!!    …

查看全部問答∨

關于ise ,求助

最近調試一段程序,synthesize是沒有問題的,但是當implement的時候,出現如下warningWARNING:NgdBuild:1012 - The constraint <NET "ld_out[1]" LOC = P15;> [top.ucf(49)] is overridden on the design object XLXI_2/ld_out<1 ...…

查看全部問答∨

[轉帖]STM32內置參照電壓的使用

每個STM32芯片都有一個內部的參照電壓,相當于一個標準電壓測量點,在芯片內部連接到ADC1的通道17。 根據數據手冊中的數據,這個參照電壓的典型值是1.20V,最小值是1.16V,最大值是1.24V。這個電壓基本不隨外部供電電壓的變化而變化。 不少 ...…

查看全部問答∨

問個bootloader的問題?

我在上電后,從flash裝載程序,有時能正常運行,有時不運行,是什么原因啊?寫到flash里的應該是對的,不然肯定是一直都不會運行的,是不是flash和dsp之間的線有虛焊什么的?還有其他的原因嗎?…

查看全部問答∨

UART模塊問題

我現在有一塊板,p3.3接422-TEN,p3.4接422-TIN,p3.5接422-OUT,外接時鐘是32768Hz,程序如下: void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P3SEL |= 0x38; // P3.3,4,5 = UCLK0,USART0 TXD/ ...…

查看全部問答∨

現在學習zigbee 用什么板子好呢?

我的畢業論文是關于zigbee的,要求演示個簡單的實驗,大家給點建議,用什么產品好呢?…

查看全部問答∨

C51單片入門的好程序

C51單片入門的好程序,祝大家學的愉快…

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

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

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

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 石棉县| 温宿县| 斗六市| 沙坪坝区| 婺源县| 邵阳市| 宣武区| 邓州市| 澄迈县| 澄城县| 凤台县| 康乐县| 太仓市| 乐昌市| 磴口县| 修水县| 泌阳县| 六枝特区| 东宁县| 峡江县| 天等县| 巫山县| 井陉县| 阳东县| 丁青县| 长武县| 尼木县| 饶阳县| 军事| 河西区| 武安市| 伊宁县| 和田县| 桐梓县| 桂东县| 嘉禾县| 商水县| 南陵县| 平遥县| 紫云| 岐山县|