______________________________________________________________________ > < > Internal PIC18 EEPROM driver v1.00 < > for < > PICos18 release 2.03 < > < > PICos18 - Real-time kernel for PIC18 family < > < > < > www.picos18.com www.pragmatec.net < >______________________________________________________________________< This file contains all necessary informations to use properly the Internal PIC18 EEPROM driver for PICos18 v2.xx. This driver lets you design a multi-task application using the same EEPROM interface without being concerned by the EEPROM shared access. Then every task of your application can read and write data from/to the EEPROM at the same time. ______________________________________________________________________ > < > I - Zip file content < >______________________________________________________________________< The Eeprom_int zip file contains : - Eeprom_int.c - Eeprom_int.h : header file - Eeprom_int.txt : this file To use the Internal PIC18 EEPROM driver, first unzip the file. Place the C and H files in your project directory. This driver is supposed to be use with PICos18 and has been tested with MPLAB 7.10 and C18 v2.40. This driver is suitable for PIC18 with internal EEPROM of 512 or 1024 bytes. ______________________________________________________________________ > < > II - Hardware settings < >______________________________________________________________________< The code provided is named a driver. Actually it is much more a library (a set of functions) than a driver (a task connected to an ISR). Then to use the Internal PIC18 EEPROM driver you just have to include the C and H files to your project and add a "#include "Eeprom_int.h"" in each C file that needs to access the internal EEPROM. If you build the project just after adding the files you should get the following message : "you should define a 512 or 1024 byte EEPROM size !" If the PIC18 you choose have less than 512 bytes of EEPROM then build the project with the "-D__EEPROM512__" option. To do it, add the following compiler option in the MPLAB C18 panel of the Build Options window : __EEPROM512__ If the PIC18 you choose has more than 512 bytes of EEPROM then build the project with the "-D__EEPROM1024__" option. To do it, add the following compiler option in the MPLAB C18 panel of the Build Options window : __EEPROM1024__ If you forget to select any compiler option, the compiler will exit with an error message : "you should define a 512 or 1024 byte EEPROM size !" ______________________________________________________________________ > < > III - TASCDESC settings < >______________________________________________________________________< The PIC18 Internal EEPROM is a shared resource. It means it is an unique peripheral but many tasks of your application can try to use it at the same time. PICos18 manages shared resources according to the OSEK CEILING PROTOCOL. You need first to declare the resource in the tascdesc.c file : /********************************************************************** * ------------------------ RESOURCE DEFINITION ----------------------- **********************************************************************/ Resource Resource_list[] = { { RESOURCE_EE_PRIO, /* priority */ 0, /* Task prio */ 0, /* lock */ } }; #define _RESOURCENUMBER_ sizeof(Resource_list)/sizeof(Resource) unsigned char RESOURCENUMBER = _RESOURCENUMBER_; ______________________________________________________________________ > < > IV - PRIORITY settings < >______________________________________________________________________< The PIC18 internal EEPROM is a shared resource. It means it is something unique that can be reached by any task present in the application. The risk is then to have multiple access to the EEPROM at the same time. To avoid this problem of synchronization between task the OSEK standard specifies to use the CEILING PROTOCOL mecanism. The CEILING PROTOCOL is implemented in PICos18. This lets you add a special priority to the shared resource. This priority has to be higher than any task trying to access to the shared resource. Here is an example whith 2 tasks (TASKIN and TASKOUT) and 2 drivers : #define TASKIN_PRIO 8 #define TASKOUT_PRIO 9 #define RESOURCE_EE_PRIO 10 // EEPROM RESOURCE #define DRV_I2C_PRIO 11 #define RDV_RS_PRIO 12 #define RESOURCE_EE_ID 0 // First element of the list Each time one of the both tasks will try to access the EEPROM resource then the priority of the requesting task will change to the a new value (the one of the resource). Then at one specific moment the task using the EEPROM resource will have a relative high priority and won't be disturb by another task that can ask for an EEPROM access. For instance if the TASKIN task wants to use the PIC18 Internal EEPROM driver it will take at first the priority of the EEPROM resource (10), then the TASKOUT task will have a lowest priority and won't disturb the TASKIN task during EEPROM access. This mecanism is managed automaticaly by the PICos18 kernel, you just have to call a specific function before calling the PIC18 Internal EEPROM functions. Have a look at the following example to learn how to use it. ______________________________________________________________________ > < > V - Internal PIC18 EEPROM usage < >______________________________________________________________________< First of all you need to set a resource value in the define.h file (cf previous chapter), and to specify the __EEPROM512__ compiler option. In the TASKIN task, include the driver header: #include "Eeprom_int.h" And declare a buffer in RAM to store data from EEPROM: unsigned char zero; // special buffer 1 byte long ! See hereafter a basic example to have a secure access to the EEPROM: #include "define.h" #include "Eeprom_int.h" /********************************************************************** * --------------------------- TASKIN task ---------------------------- * * This task erases the first 100 bytes of the EEPROM. * **********************************************************************/ TASK(TASKIN_ID) { unsigend char index; zero = 0; if (GetResource(RESOURCE_EE_ID) == E_OK) { for (index = 0; index < 100; index++) WriteEEPROM(index, 1, &zero); ReleaseResource(RESOURCE_EE_ID); } SetRelAlarm(0, 100, 100); while (1) { WaitEvent(ALARM_EVENT); ClearEvent(ALARM_EVENT); /* ... */ } } ______________________________________________________________________ > < > V - Internal PIC18 EEPROM usage (2) < >______________________________________________________________________< Here is a second task using the EEPROM periodicaly. It is so necessary to use the GetResource function to be sure to lock the shared resource during the access. In the TASKIN task, include the driver header: #include "Eeprom_int.h" And declare a buffer in RAM to store data from EEPROM: unsigned char buf[10]; See hereafter a basic example to have a secure access to the EEPROM: #include "define.h" #include "Eeprom_int.h" /********************************************************************** * --------------------------- TASKIN task ---------------------------- * * This task erases the first 100 bytes of the EEPROM. * **********************************************************************/ TASK(TASKOUT_ID) { SetRelAlarm(0, 1000, 1000); while (1) { WaitEvent(ALARM_EVENT); ClearEvent(ALARM_EVENT); /* We inspect the EEPROM content every 1 seconde */ if (GetResource(RESOURCE_EE_ID) == E_OK) { ReadEEPROM(0, 10, buf); ReleaseResource(RESOURCE_EE_ID); /* If content is a valid frame */ if ((buf[0] == 0x17) && (buf[9] == 0x19)) { DecodeFrame(buf); /* ... */ } } } } ______________________________________________________________________ > < > VI - Conclusion < >______________________________________________________________________< The GetResource function has the ability to change the task priotity dynamicaly. PICos18 is a real time kernel then the scheduler is called immediatly in order to find out wich task in a READY state has the highest priority (the task with its brand new priority could have a higher priority than the current task, then a task switching is necessary). Such an algorithm is called CEILING PROTOCOL in the OSEK standard. It is quite elegant but the bottleneck is the time the kernel needs to switch context : indeed each time you call the GetResource or ReleaseResource functions you will need 50 µs of switch context. If your application needs to reach high performance, try to call the GetResource outside of a FOR loop and not inside (like in the previous examples). Last but not least, the time you need to write data in the Internal EEPROM is quite long : 10ms ! Reading from the EEPROM is the same than from the RAM area, not any additionnal time is needed. /* End of File : Eeprom_int.txt */