I want to hook all the BlockIo protocols,but I don't know whether the BlockIo protocol of logical partions is produced based on the BlockIo protocol of the hardware device which the logical partions belongs to! My hook code is shown as follow.
EFI_BLOCK_IO_PROTOCOL* OldBlockIO=NULL;
EFI_BLOCK_IO_PROTOCOL* NewBlockIO=NULL;
EFI_STATUS EFIAPI NewReadBlocks(IN EFI_BLOCK_IO_PROTOCOL *This,IN UINT32 MediaId,IN EFI_LBA LBA,IN UINTN BufferSize,OUT VOID *Buffer)
{
//do other things
return OldBlockIO->ReadBlocks(OldBlockIO,MediaId,LBA,BufferSize,Buffer);
}
EFI_STATUS EFIAPI NewWriteBlocks(IN EFI_BLOCK_IO_PROTOCOL *This,IN UINT32 MediaId,IN EFI_LBA LBA,IN UINTN BufferSize,IN VOID *Buffer)
{
//do other things
return OldBlockIO->WriteBlocks(OldBlockIO,OldBlockIO->Media->MediaId,LBA,BufferSize,Buffer);
}
EFI_STATUS EFIAPI HookBlockIOProtocol()
{
EFI_STATUS Status=EFI_SUCCESS;
/*
Allocating memory for NewBlockIO
copy OldBlockIo to NewBlockIo
*/
//overridde the members
NewBlockIO->ReadBlocks=(EFI_BLOCK_READ)NewReadBlocks;
NewBlockIO->WriteBlocks=(EFI_BLOCK_WRITE)NewWriteBlocks;
//hook block io using ReinstallProtocolInterface boot service
Status=gBS->ReinstallProtocolInterface(BlockControllerHandles[0],&gEfiBlockIoProtocolGuid,(VOID*)OldBlockIO[0],(VOID*)NewBlockIO[0]);
if (EFI_ERROR(Status))
{
gBS->FreePool((VOID*)NewBlockIO[0]);
Print(L"(HookBlockIOProtocol0:Print)gBS->ReinstallProtocolInterface for BlockControllerHandles[0]=%p failed,status=%d.\r\n",BlockControllerHandles[0],Status);
PauseProgram();
}
return Status;
}
Related
I want to create simple weather station with esp8266 but with scheduler to updating data and GUI more simultaneously. I've downloaded scheduler from here but there is information:
Tasks must be declared globally on the stack (not a pointer). Failure to do so will crash your device
Does that mean that I have to write all task classes in *.ino file? Can I save them in separate files and call to sketch file? How to do that? I've tried few times but the code won't compile.
Simpliest example of sketch:
#include <Scheduler.h>
#include <Arduino.h>
class SimpleTask : public Task {
protected:
void setup() {
Serial.println("Setup func");
}
void loop() {
Serial.println("Loop func");
delay(600);
}
} simple_task;
void setup() {
Serial.begin(115200);
Scheduler.start(&simple_task);
Scheduler.begin();
}
void loop() { }
Tasks must be declared globally on the stack (not a pointer).
I think strictly this means that Tasks must not be created on the heap and need to be global, static objects.
This can be done by creating the object in a separate file and declaring the object using the extern keyword.
e.g. an example mysimpletask.h:
#ifndef __MySIMPLETASK_H__
#define __MySIMPLETASK_H__
#include <Scheduler.h>
class MySimpleTask : public Task {
protected:
void setup();
void loop();
};
extern MySimpleTask my_simple_task;
#endif
The implementation in mysimpletask.cpp:
#include "mysimpletask.h"
void MySimpleTask::setup() {
Serial.println("Setup func");
}
void MySimpleTask::loop() {
Serial.println("Loop func");
delay(600);
}
MySimpleTask my_simple_task;
And the sketch:
#include <Scheduler.h>
#include <Arduino.h>
#include "mysimpletask.h"
void setup() {
Serial.begin(115200);
Scheduler.start(&my_simple_task);
Scheduler.begin();
}
void loop() { }
I made a static library in C language.
The functions of this library are as follows.
Save the callback function point in a global variable
The callback function has a parameter of the struct structure.
The library transmits struct data by calling the callback function to the library user at a specific moment.
The source for this is:
static library source
// ---------------------------------------------
// Static Library
// ---------------------------------------------
typedef struct
{
unsigned long m_Data1;
unsigned long m_Data2;
unsigned long m_Data3;
} SEND_DATA;
//
typedef int (*ReportCallbackProc)(SEND_DATA *pSendData);
//
static ReportCallbackProc gReportFunc = NULL;
static Period = 0;
// Set callback function pointer to gloval variable
int SetReport(ReportCallbackProc func, int period)
{
gReportFunc = func;
Period = period;
return(1);
}
// Send data to Application of library
void Report()
{
.............
SEND_DATA sendData;
sendData.m_Data1 = 1;
sendData.m_Data2 = 2;
sendData.m_Data3 = 3;
int rc = gReportFunc(&sendData);
if (rc != 1)
{
printf("gRealtimeReportFunc failed: status=[%d]\n", rc);
}
.....
}
application of this library
// ---------------------------------------------
// Application of Static Library
// ---------------------------------------------
void handle_report (SEND_DATA *pSendData)
{
printf("Report called");
printf("m_Data1 = %ld ", pSendData->m_Data1);
printf("m_Data2 = %ld ", pSendData->m_Data2);
printf("m_Data3 = %ld ", pSendData->m_Data3);
}
void main()
{
SetReport (&handle_report, period);
}
I want to make the above source in swift. Currently, I am trying to implement while studying swift.
However, it is not an easy problem and asks for help.
I tried creating and implementing closure usage and classes, but it was never easy.
Can you provide similar swift code?
Can you tell me how to implement it?
I am new to device drivers and I was learning this container_of and dev_get_drvdata and came across this driver.I removed some partof this driver so as to make it compact.
static void tsl4531_polling_worker(struct work_struct *work)
{
u8 buf[2];
struct tsl4531_data *data = container_of(to_delayed_work(work),
struct tsl4531_data, work);
mutex_lock(&data->update_lock);
buf[0] = DEVICE_LIGHT;
buf[1] = GET_REQUEST;
sam4l_send_request(data->pdata.sam4l,2,buf);
mutex_unlock(&data->update_lock);
}
static ssize_t store_enable_value(struct device *dev,struct device_attribute *devattr,const char *buf,size_t count){
struct tsl4531_data *data = dev_get_drvdata(dev);
if((buf[0] == '1') && (!tsl4531_enabled)) {
schedule_delayed_work(&data->work, msecs_to_jiffies(50));
tsl4531_enabled = 1;
} else if (buf[0] == '0'){
tsl4531_enabled = 0;
cancel_delayed_work_sync(&data->work);
tsl4531_lux = 0;
}
return count;
}
static DEVICE_ATTR(enable,S_IRUGO | S_IWUGO,
show_enable_value, store_enable_value );
static struct attribute *tsl4531_attributes[] = {
&dev_attr_lux_show.attr,
&dev_attr_enable.attr,
NULL
};
static const struct attribute_group tsl4531_attr_group = {
.attrs = tsl4531_attributes,
};
void tsl4531_callback_fun(struct work_struct *work)
{
struct tsl4531_data *chip = container_of(work,struct tsl4531_data,
pdata.work.work);
tsl4531_lux = chip->pdata.response[2];//Need to check on which response index we get lux value
input_report_abs(tsl4531_dev, ABS_X,tsl4531_lux);
input_sync(tsl4531_dev);
schedule_delayed_work(&chip->work, msecs_to_jiffies(1500));
}
static int __devinit tsl4531_probe(struct platform_device *pdev){
struct tsl4531_data *chip;
int err=0;
chip = kzalloc(sizeof(struct tsl4531_data), GFP_KERNEL);
if (!chip){
dev_dbg(&pdev->dev, "memory not allocated for tsl4531 light sensor module.\n");
return -ENOMEM;
}
dev_set_drvdata(&pdev->dev,chip);//here we give address in chip to struct device
tsl4531_dev=input_allocate_device();
if(!tsl4531_dev) {
dev_dbg(&pdev->dev, "memory not allocated for tsl4531_dev.\n");
return -ENOMEM;
}
err=input_register_device(tsl4531_dev);
if(err){
dev_dbg(&pdev->dev, "input register poll the device failed ... \n");
goto err_reg_poll;
}
mutex_init(&chip->update_lock);
err = sysfs_create_group(&pdev->dev.kobj,&tsl4531_attr_group);
if (err){
dev_dbg(&pdev->dev, "creating sysfs group for tsl4531 sensor module failed.\n");
goto exit_err;
}
INIT_DELAYED_WORK(&chip->work, tsl4531_polling_worker);
INIT_DELAYED_WORK(&chip->pdata.work,tsl4531_callback_fun);
chip->pdata.dev_id = DEVICE_LIGHT;
return 0;
return err;
}
static int __devexit tsl4531_remove(struct platform_device *pdev){
struct tsl4531_data *data = dev_get_drvdata(&pdev->dev);
cancel_delayed_work_sync(&data->work);
cancel_delayed_work(&data->pdata.work);
sysfs_remove_group(&pdev->dev.kobj, &tsl4531_attr_group);
unregister_sam4l_client(&data->pdata);
kfree(data);
return 0;
}
static const struct platform_device_id tsl4531_id[] = {
{ "tsl45317", 0 },
{ }
};
static struct platform_driver tsl4531_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tsl45317",
},
.probe = tsl4531_probe,
.remove = tsl4531_remove,
.suspend = tsl4531_suspend,
.resume = tsl4531_resume,
.id_table = tsl4531_id,
};
static int __init tsl4531_init(void){
return platform_driver_register(&tsl4531_driver);
}
static void __exit tsl4531_exit(void){
platform_driver_unregister(&tsl4531_driver);
}
I have few doubts regarding working of container_of and dev_get_drvdata
1)in the polling_worker function we can see one container_of macro which fetches the address to the original structure and assigned to struct tsl4531_data *data;
2)in the probe function we can see one call to dev_set_drvdata and in store_enable_value and tsl4531 dev_get_drvdata.
Isn't both container_of and dev_set and dev_get doing same things here?
container_of and dev_set, dev_get are different. But yes, the intention might be the same. Both are actually used to retrieve the pointer (usually to the private data structure of the device).
container_of() actually does a reverse mapping. It does the opposite of &struct_base->member operation. In the previous operation you have the pointer to the base of the structure and need the address of one of its member. While, container_of takes in the address of the member and returns the base address. In the tsl4531_polling_worker() function, it has the member's address and using container_of it is getting the base address of the structure (struct tsl4531_data)
dev_set_drvdata() is generally used to preserve a pointer's address, such that it could be retrieved later using dev_get_drvdata(). Unlike reverse mapping, the functions stores and loads the address from a pointer of type void * (refer http://lxr.free-electrons.com/source/drivers/base/dd.c#L595)
I have an element that decodes a media type, mytype for example. I want to register the type so that the decodebin element can use my element if needed. I added the code for what I thought would work, but my type_find() function is never called. Any ideas on what I'm doing wrong? Here's what the code looks like:
#define MY_CAPS (gst_static_caps_get(&my_caps))
static GstStaticCaps my_caps = GST_STATIC_CAPS("audio/x-mycaps");
static gchar *my_exts[] = { "mtype", NULL };
static void type_find(GstTypeFind *_type_find, gpointer callback)
{
printf("Type Find Function\r\n");
gst_type_find_suggest(_type_find, GST_TYPE_FIND_POSSIBLE, gst_static_caps_get(&my_caps));
}
gboolean plugin_init(GstPlugin *plugin)
{
if(!gst_type_find_register(plugin, "mytype", GST_RANK_PRIMARY, type_find, my_exts, MY_CAPS, NULL, NULL))
return FALSE;
if(!gst_element_register(plugin, "myelement", GST_RANK_PRIMARY, MY_ELEMENT_TYPE)
return FALSE;
return(TRUE);
}
In GTK+, is it possible to access the GtkWidget -- text entry for file name in GtkFileChooser? I want to disable the editable attribute of the text entry using gtk_entry_set_editable.
As far as I know, no.
What do you ultimately want to achieve? Perhaps there is another approach.
If one had a legitimate reason to get a pointer to the GtkEntry, then derive from GtkFileChooserDialog, which will probably mutate into a GtkFileChooserDefault. GObject will complain about an illegal cast when checking type instance even though it works and the data of derived object can be accessed without errors, use GTK_FILE_CHOOSER instead of MY_FILE_CHOOSER to avoid the warning messages and a local static for the entry pointer. The entry widget is NOT accessible during construction. Here is the pertinent code:
static GtkEntry *chooser_entry;
static void my_file_chooser_finalize (GObject *object)
{
chooser_entry = NULL;
(G_OBJECT_CLASS (my_file_chooser_parent_class))->finalize (object);
}
static void my_file_chooser_init (MyFileChooser *self)
{
chooser_entry = NULL;
}
static void look_for_entry(GtkWidget *widget, void *self)
{
if (GTK_IS_ENTRY(widget)) {
chooser_entry = (GtkEntry*)widget;
}
else if (GTK_IS_CONTAINER(widget)) {
gtk_container_forall ( GTK_CONTAINER (widget), look_for_entry, self);
}
}
static void file_chooser_find_entry (GtkWidget *chooser)
{
GList *children, *iter;
/* Get all objects inside the dialog */
children = gtk_container_get_children (GTK_CONTAINER (chooser));
for (iter = children; iter; iter = iter->next) {
if (GTK_IS_CONTAINER(iter->data)) {
gtk_container_forall ( GTK_CONTAINER (iter->data), look_for_entry, chooser);
if (chooser_entry != NULL) {
break;
}
}
}
g_list_free (children);
}
GtkEntry *my_file_chooser_get_entry (GtkWidget *widget)
{
if (chooser_entry == NULL) {
file_chooser_find_entry (widget);
}
return chooser_entry;
}
char *my_file_chooser_get_entry_text(GtkWidget *widget)
{
char *text;
GtkEntry *entry;
text = NULL;
if (GTK_IS_FILE_CHOOSER(widget)) {
entry = my_file_chooser_get_entry(widget);
if (GTK_IS_ENTRY(entry)) {
if (gtk_entry_get_text_length (entry)) {
text = g_strdup (gtk_entry_get_text(entry));
}
}
}
return text;
}
Maybe not ideal, but works.