/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pcilib/pcipywrap.c

  • Committer: Vasilii Chernov
  • Date: 2016-02-05 11:33:48 UTC
  • mto: This revision was merged to the branch mainline in revision 353.
  • Revision ID: vchernov@inr.ru-20160205113348-l4gmpvm9df3n22sx
Add support for python script properties. Correct pcilib python wrapping. Update examples. Update cmakelists for work in shadow build mode.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include "pcilib.h"
2
 
 
3
 
//Remove unused headers
4
 
#include <stdio.h>
5
 
#include <stdlib.h>
6
 
#include <string.h>
7
 
#include <strings.h>
8
 
#include <stdint.h>
9
 
#include <stdarg.h>
10
 
#include <fcntl.h>
11
 
#include <unistd.h>
12
 
#include <sys/time.h>
13
 
#include <sys/ioctl.h>
14
 
#include <sys/mman.h>
15
 
#include <errno.h>
16
 
#include <alloca.h>
17
 
#include <arpa/inet.h>
18
 
#include <sys/types.h>
19
 
#include <sys/stat.h>
20
 
#include <dirent.h>
21
 
#include <pthread.h>
22
 
#include <signal.h>
23
 
#include <dlfcn.h>
24
 
 
25
 
#include <getopt.h>
26
 
 
27
 
#include <fastwriter.h>
28
 
 
29
 
#include "pcitool/sysinfo.h"
30
 
#include "pcitool/formaters.h"
31
 
 
32
 
#include "views/transform.h"
33
 
#include "views/enum.h"
 
2
#include <Python.h>
34
3
#include "pci.h"
35
 
#include "plugin.h"
36
 
#include "config.h"
37
 
#include "tools.h"
38
 
#include "kmem.h"
39
4
#include "error.h"
40
 
#include "debug.h"
41
 
#include "model.h"
42
 
#include "locking.h"
43
5
 
 
6
/*!
 
7
 * \brief Global pointer to pcilib_t context.
 
8
 * Used by __setPcilib and read_register.
 
9
 */
44
10
pcilib_t* __ctx = 0;
45
 
pcilib_model_description_t *model_info = 0;
46
 
 
47
 
/*!
48
 
 * \brief присваивание указателя на устройство. Закрытая функция. Будет проходить при парсинге xml.
49
 
 * \param ctx
50
 
 */
51
 
void __initCtx(void* ctx)
52
 
{
53
 
    __ctx = ctx;
54
 
}
55
 
 
56
 
/*!
57
 
 * \brief создание хэндлера устройства, для тестирования скрипта не из программы.
58
 
 * \return
59
 
 */
60
 
void __createCtxInstance(const char *fpga_device, const char *model)
61
 
{
62
 
    __ctx = pcilib_open(fpga_device, model);
63
 
    model_info = pcilib_get_model_description(__ctx);
64
 
}
65
 
 
66
 
int read_register(const char *bank, const char *regname, void *value)
67
 
{
68
 
    int ret = pcilib_read_register(__ctx, bank, regname, (pcilib_register_value_t*)value);
69
 
    return ret;
70
 
}
71
 
 
72
 
void Error(const char *message, const char *attr, ...)
73
 
{
74
 
                printf("Catch error: %s, %s\n", message, attr);
75
 
}
76
 
 
77
 
int ReadRegister(const char *bank, const char *reg) {
78
 
    
79
 
    const char *view = NULL;
80
 
    const char *unit = NULL;
81
 
    const char *attr = NULL;
82
 
    pcilib_t *handle = __ctx;
83
 
    int i;
84
 
    int err;
85
 
    const char *format;
86
 
 
87
 
    pcilib_register_bank_t bank_id;
88
 
    pcilib_register_bank_addr_t bank_addr = 0;
89
 
 
90
 
    pcilib_register_value_t value;
91
 
 
92
 
        // Adding DMA registers
93
 
    pcilib_get_dma_description(handle);
94
 
 
95
 
    if (reg||view||attr) {
96
 
        pcilib_value_t val = {0};
97
 
        if (attr) {
98
 
            if (reg) err = pcilib_get_register_attr(handle, bank, reg, attr, &val);
99
 
            else if (view) err = pcilib_get_property_attr(handle, view, attr, &val);
100
 
            else if (bank) err = pcilib_get_register_bank_attr(handle, bank, attr, &val);
101
 
            else err = PCILIB_ERROR_INVALID_ARGUMENT;
102
 
 
103
 
            if (err) {
104
 
                if (err == PCILIB_ERROR_NOTFOUND)
105
 
                    Error("Attribute %s is not found", attr);
106
 
                else
107
 
                    Error("Error (%i) reading attribute %s", err, attr);
108
 
            }
109
 
 
110
 
            err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
111
 
            if (err) Error("Error converting attribute %s to string", attr);
112
 
 
113
 
            printf("%s = %s", attr, val.sval);
114
 
            if ((val.unit)&&(strcasecmp(val.unit, "name")))
115
 
                printf(" %s", val.unit);
116
 
            printf(" (for %s)\n", (reg?reg:(view?view:bank)));
117
 
        } else if (view) {
118
 
            if (reg) {
119
 
                err = pcilib_read_register_view(handle, bank, reg, view, &val);
120
 
                if (err) Error("Error reading view %s of register %s", view, reg);
121
 
            } else {
122
 
                err = pcilib_get_property(handle, view, &val);
123
 
                if (err) Error("Error reading property %s", view);
124
 
            }
125
 
 
126
 
            if (unit) {
127
 
                err = pcilib_convert_value_unit(handle, &val, unit);
128
 
                if (err) {
129
 
                    if (reg) Error("Error converting view %s of register %s to unit %s", view, reg, unit);
130
 
                    else Error("Error converting property %s to unit %s", view, unit);
131
 
                }
132
 
            }
133
 
            
134
 
            err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
135
 
            if (err) {
136
 
                if (reg) Error("Error converting view %s of register %s to string", view);
137
 
                else Error("Error converting property %s to string", view);
138
 
            }
139
 
 
140
 
            printf("%s = %s", (reg?reg:view), val.sval);
141
 
            if ((val.unit)&&(strcasecmp(val.unit, "name")))
142
 
                printf(" %s", val.unit);
143
 
            printf("\n");
144
 
        } else {
145
 
            pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
146
 
            bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank);
147
 
            format = model_info->banks[bank_id].format;
148
 
            if (!format) format = "%lu";
149
 
            err = pcilib_read_register_by_id(handle, regid, &value);
150
 
            if (err) Error("Error reading register %s", reg);
151
 
 
152
 
            printf("%s = ", reg);
153
 
            printf(format, value);
154
 
            printf("\n");
155
 
        }
156
 
    } else {
157
 
        if (model_info->registers) {
158
 
            if (bank) {
159
 
                bank_id = pcilib_find_register_bank(handle, bank);
160
 
                bank_addr = model_info->banks[bank_id].addr;
161
 
            }
162
 
            
163
 
            printf("Registers:\n");
164
 
            for (i = 0; model_info->registers[i].bits; i++) {
165
 
                if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { 
166
 
                    bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[i].bank);
167
 
                    format = model_info->banks[bank_id].format;
168
 
                    if (!format) format = "%lu";
169
 
 
170
 
                    err = pcilib_read_register_by_id(handle, i, &value);
171
 
                    if (err) printf(" %s = error reading value", model_info->registers[i].name);
172
 
                    else {
173
 
                        printf(" %s = ", model_info->registers[i].name);
174
 
                        printf(format, value);
175
 
                    }
176
 
 
177
 
                    printf(" [");
178
 
                    printf(format, model_info->registers[i].defvalue);
179
 
                    printf("]");
180
 
                    printf("\n");
181
 
                }
182
 
            }
183
 
        } else {
184
 
            printf("No registers");
185
 
        }
186
 
        printf("\n");
187
 
    }
188
 
 
189
 
    return 0;
 
11
 
 
12
/*!
 
13
 * \brief Wraps for pcilib_open function.
 
14
 * \param[in] fpga_device path to the device file [/dev/fpga0]
 
15
 * \param[in] model specifies the model of hardware, autodetected if NULL is passed
 
16
 * \return Pointer to pcilib_t, created by pcilib_open, serialized to bytearray
 
17
 */
 
18
PyObject* __createPcilibInstance(const char *fpga_device, const char *model)
 
19
{
 
20
        //opening device
 
21
    pcilib_t* ctx = pcilib_open(fpga_device, model);
 
22
    
 
23
    //serializing object
 
24
    return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*));
 
25
}
 
26
 
 
27
/*!
 
28
 * \brief Sets pcilib context to wraper.
 
29
 * \param[in] addr Pointer to pcilib_t, serialized to bytearray
 
30
 */
 
31
void __setPcilib(PyObject* addr)
 
32
{
 
33
        if(!PyByteArray_Check(addr))
 
34
        {
 
35
                PyErr_SetString(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed");
 
36
                return NULL;
 
37
        }
 
38
        
 
39
        //deserializing adress
 
40
        char* pAddr = PyByteArray_AsString(addr);
 
41
        
 
42
        //hard copy context adress
 
43
        for(int i = 0; i < sizeof(pcilib_t*) + 10; i++)
 
44
                ((char*)&__ctx)[i] = pAddr[i];
 
45
 
 
46
        free(pAddr);
 
47
}
 
48
 
 
49
/*!
 
50
 * \brief Reads register value.
 
51
 * \param[in] regname the name of the register
 
52
 * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise
 
53
 * \return register value, can be integer or float type
 
54
 */
 
55
PyObject* read_register(const char *regname, const char *bank)
 
56
{       
 
57
        if(!__ctx)
 
58
        {
 
59
                PyErr_SetString(PyExc_Exception, "pcilib_t handler not initialized");
 
60
                return NULL;
 
61
        }
 
62
    
 
63
    pcilib_get_dma_description(__ctx);
 
64
 
 
65
        pcilib_value_t val = {0};
 
66
    pcilib_register_value_t reg_value;
 
67
        
 
68
        int err; 
 
69
        
 
70
        err = pcilib_read_register(__ctx, bank, regname, &reg_value);
 
71
        if(err)
 
72
        {
 
73
                PyErr_SetString(PyExc_Exception, "Failed: read_register");
 
74
                return NULL;
 
75
        }
 
76
        
 
77
        err = pcilib_set_value_from_register_value(__ctx, &val, reg_value);
 
78
        
 
79
        if(err)
 
80
        {
 
81
                PyErr_SetString(PyExc_Exception, "Failed: pcilib_set_value_from_register_value");
 
82
                return NULL;
 
83
        }
 
84
 
 
85
        switch(val.type)
 
86
        {
 
87
                case PCILIB_TYPE_INVALID:
 
88
                        PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_INVALID)");
 
89
                        return NULL;
 
90
                        
 
91
                case PCILIB_TYPE_STRING:
 
92
                        PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_STRING)");
 
93
                        return NULL;
 
94
                
 
95
                case PCILIB_TYPE_LONG:
 
96
                {
 
97
                        long ret;
 
98
                        ret = pcilib_get_value_as_int(__ctx, &val, &err);
 
99
                        
 
100
                        if(err)
 
101
                        {
 
102
                                PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int");
 
103
                                return NULL;
 
104
                        }
 
105
                        return PyInt_FromLong((long) ret);
 
106
                }
 
107
                
 
108
                case PCILIB_TYPE_DOUBLE:
 
109
                {
 
110
                        double ret;
 
111
                        ret = pcilib_get_value_as_float(__ctx, &val, &err);
 
112
                        
 
113
                        if(err)
 
114
                        {
 
115
                                PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int");
 
116
                                return NULL;
 
117
                        }
 
118
                        return PyFloat_FromDouble((double) ret);
 
119
                }
 
120
                
 
121
                default:
 
122
                        PyErr_SetString(PyExc_Exception, "Invalid register output type (unknown)");
 
123
                        return NULL;
 
124
        }
190
125
}